Tôi muốn thay đổi việc triển khai phụ thuộc được chế tạo trên một cơ sở thử nghiệm đơn lẻ bằng cách mở rộng hành vi của mô hình mặc định và hoàn nguyên nó về triển khai ban đầu khi thử nghiệm tiếp theo thực hiện.
Nói ngắn gọn hơn, đây là những gì tôi đang cố gắng đạt được:
- sự phụ thuộc giả
- thay đổi / mở rộng triển khai mô hình trong một thử nghiệm duy nhất
- hoàn nguyên về mô hình ban đầu khi thử nghiệm tiếp theo thực hiện
Tôi hiện đang sử dụng Jest v21
.
Đây là một bài kiểm tra Jest điển hình sẽ trông như thế nào:
__mocks__/myModule.js
const myMockedModule = jest.genMockFromModule('../myModule');
myMockedModule.a = jest.fn(() => true);
myMockedModule.b = jest.fn(() => true);
export default myMockedModule;
__tests__/myTest.js
import myMockedModule from '../myModule';
// Mock myModule
jest.mock('../myModule');
beforeEach(() => {
jest.clearAllMocks();
});
describe('MyTest', () => {
it('should test with default mock', () => {
myMockedModule.a(); // === true
myMockedModule.b(); // === true
});
it('should override myMockedModule.b mock result (and leave the other methods untouched)', () => {
// Extend change mock
myMockedModule.a(); // === true
myMockedModule.b(); // === 'overridden'
// Restore mock to original implementation with no side effects
});
it('should revert back to default myMockedModule mock', () => {
myMockedModule.a(); // === true
myMockedModule.b(); // === true
});
});
Đây là những gì tôi đã thử cho đến nay:
1 - mockFn.mockImplementationOnce (fn)
thuận
- Hoàn nguyên về triển khai ban đầu sau cuộc gọi đầu tiên
khuyết điểm
- Nó bị hỏng nếu thử nghiệm gọi
b
nhiều lần - Nó không hoàn nguyên về triển khai ban đầu cho đến khi
b
không được gọi (rò rỉ trong thử nghiệm tiếp theo)
mã:
it('should override myModule.b mock result (and leave the other methods untouched)', () => {
myMockedModule.b.mockImplementationOnce(() => 'overridden');
myModule.a(); // === true
myModule.b(); // === 'overridden'
});
2 - jest.doMock (moduleName, factory, options)
thuận
- Chế nhạo lại rõ ràng mọi bài kiểm tra
khuyết điểm
- Không thể xác định triển khai mô hình mặc định cho tất cả các thử nghiệm
- Không thể mở rộng triển khai mặc định buộc phải khai báo lại từng phương thức bị chế nhạo
mã:
it('should override myModule.b mock result (and leave the other methods untouched)', () => {
jest.doMock('../myModule', () => {
return {
a: jest.fn(() => true,
b: jest.fn(() => 'overridden',
}
});
myModule.a(); // === true
myModule.b(); // === 'overridden'
});
3 - Mô phỏng thủ công với các phương pháp setter (như được giải thích ở đây )
thuận
- Toàn quyền kiểm soát các kết quả bị chế nhạo
khuyết điểm
- Rất nhiều mã lò hơi
- Khó duy trì lâu dài
mã:
__mocks__/myModule.js
const myMockedModule = jest.genMockFromModule('../myModule');
let a = true;
let b = true;
myMockedModule.a = jest.fn(() => a);
myMockedModule.b = jest.fn(() => b);
myMockedModule.__setA = (value) => { a = value };
myMockedModule.__setB = (value) => { b = value };
myMockedModule.__reset = () => {
a = true;
b = true;
};
export default myMockedModule;
__tests__/myTest.js
it('should override myModule.b mock result (and leave the other methods untouched)', () => {
myModule.__setB('overridden');
myModule.a(); // === true
myModule.b(); // === 'overridden'
myModule.__reset();
});
4 - jest.spyOn (object, methodName)
khuyết điểm
- Tôi không thể hoàn nguyên trở
mockImplementation
lại giá trị trả về bị chế nhạo ban đầu, do đó sẽ ảnh hưởng đến các thử nghiệm tiếp theo
mã:
beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
});
// Mock myModule
jest.mock('../myModule');
it('should override myModule.b mock result (and leave the other methods untouched)', () => {
const spy = jest.spyOn(myMockedModule, 'b').mockImplementation(() => 'overridden');
myMockedModule.a(); // === true
myMockedModule.b(); // === 'overridden'
// How to get back to original mocked value?
});