Mi piacerebbe cambiare l'implementazione di una dipendenza deriso su una base per basi di prova unico per l'estensione del finto di default 's comportamento e tornando indietro per l'implementazione originale quando il prossimo esegue test.
Più brevemente questo è ciò che sto cercando di ottenere:
- finta dipendenza
- modificare / estendere l'implementazione fittizia in un singolo test
- torna al mock originale quando viene eseguito il test successivo
Attualmente sto usando Jest v21
.
Ecco come sarebbe un tipico test Jest:
__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
});
});
Ecco cosa ho provato finora:
1 - mockFn.mockImplementationOnce (fn)
professionisti
- Torna all'implementazione originale dopo la prima chiamata
contro
- Si interrompe se il test chiama
b
più volte - Non torna all'implementazione originale fino a quando
b
non viene chiamato (fuoriuscita nel test successivo)
codice:
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)
professionisti
- Ridefinisce esplicitamente ad ogni test
contro
- Impossibile definire l'implementazione fittizia predefinita per tutti i test
- Impossibile estendere l'implementazione predefinita costringendo a dichiarare nuovamente ogni metodo deriso
codice:
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 - Derisione manuale con metodi setter (come spiegato qui )
professionisti
- Pieno controllo sui risultati falsificati
contro
- Lotto codice boilerplate
- Difficile da mantenere a lungo termine
codice:
__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)
contro
- Non riesco a tornare al
mockImplementation
valore di ritorno originale deriso, influenzando quindi i test successivi
codice:
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?
});