İsterdim bir alay bağımlılık uygulanmasını değiştirmek başına üzerinde tek bir test temelinde tarafından varsayılan taklidi uzanan 'ın davranış ve geri dönerek orjinal uygulanması sonraki test yürütür için.
Daha kısaca başarmaya çalıştığım şey bu:
- sahte bağımlılık
- tek bir testte sahte uygulamayı değiştir / genişlet
- bir sonraki test yürütüldüğünde orijinal modele geri dönün
Şu anda kullanıyorum Jest v21
.
Tipik bir Jest testi şöyle görünür:
__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
});
});
İşte şimdiye kadar denediğim şey:
1 - mockFn.mockImplementationOnce (fn)
artıları
- İlk aramadan sonra orijinal uygulamaya geri döner
Eksileri
- Test
b
birden çok kez ararsa bozulur b
Çağrılana kadar orijinal uygulamaya geri dönmez (bir sonraki testte dışarı sızar)
kod:
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, fabrika, seçenekler)
artıları
- Her testte açıkça yeniden alay
Eksileri
- Tüm testler için varsayılan sahte uygulama tanımlanamaz
- Varsayılan uygulama, alay edilen her yöntemi yeniden bildirmeye zorlamak için genişletilemez
kod:
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 - Ayarlayıcı yöntemlerle manuel alay ( burada açıklandığı gibi )
artıları
- Alay edilen sonuçlar üzerinde tam kontrol
Eksileri
- Çok sayıda standart kod
- Uzun vadede bakımı zor
kod:
__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 (nesne, yöntemAdı)
Eksileri
- Ben Geri döndürme geri olabilir
mockImplementation
, bu nedenle sonraki testler özgün alay dönüş değerine etki eden
kod:
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?
});