Ich habe Probleme, eine statische Methode im Scherz zu verspotten. Stellen Sie sich vor, Sie haben eine Klasse A mit einer statischen Methode:
export default class A {
f() {
return 'a.f()'
}
static staticF () {
return 'A.staticF()'
}
}
Und eine Klasse B, die A importiert
import A from './a'
export default class B {
g() {
const a = new A()
return a.f()
}
gCallsStaticF() {
return A.staticF()
}
}
Jetzt wollen Sie A verspotten. Es ist einfach, f() zu verspotten:
import A from '../src/a'
import B from '../src/b'
jest.mock('../src/a', () => {
return jest.fn().mockImplementation(() => {
return { f: () => { return 'mockedA.f()'} }
})
})
describe('Wallet', () => {
it('should work', () => {
const b = new B()
const result = b.g()
console.log(result) // prints 'mockedA.f()'
})
})
Ich konnte jedoch keine Dokumentation darüber finden, wie man A.staticF mockt. Ist das möglich?
Peter Stonham
Sie können den Mock einfach der statischen Methode zuweisen
import A from '../src/a'
import B from '../src/b'
jest.mock('../src/a')
describe('Wallet', () => {
it('should work', () => {
const mockStaticF = jest.fn().mockReturnValue('worked')
A.staticF = mockStaticF
const b = new B()
const result = b.gCallsStaticF()
expect(result).toEqual('worked')
})
})
Und dann kann man das auch expect(mockStaticF).toBeCalled() geben Sie Behauptungen ein, obwohl die gebundene Version nicht funktioniert (z expect(A.staticF).toBeCalled() würde werfen)
– DavidA
2. Dezember 2019 um 11:04 Uhr
Gute Lösung @Peter Du hast mir 2020 wirklich den Tag gerettet. Vielen Dank.
– Mohit
19. Januar 2020 um 18:08 Uhr
Warum bind in diesem Fall verwenden? Könnte es nicht einfacher sein, einfach zuzuordnen mockStaticF zu A.staticF? z.B A.staticF = mockStaticF
– Todd Drinkwater
3. Februar 2020 um 7:28 Uhr
kann auch ‘staticF’ außerhalb von ‘describe’ verspotten, zB jest.mock('../src/a', () => { const A = jest.fn().mockImplementation(() => { f: () => { return 'mockedA.f()'} } }); A.staticF = jest.fn(); return A; })
– Frank
30. April 2020 um 22:08 Uhr
Hier gibt es zwei Probleme, die nicht berücksichtigen, wie Jest funktioniert. Verspotten Sie niemals Methoden mit Zuweisungen wie A.staticF = mockStaticF Wenn Sie dies nicht vermeiden können, verhindert dies, dass Jest Methoden wiederherstellt, wo dies erforderlich ist, und führt möglicherweise zu einer Kreuzkontamination des Tests. Dafür ist jest.spyOn gedacht. jest.mock('../src/a') macht einen Auto-Mock, es macht statische Methode bereits zu einem Stub, der dies zulässt A.staticF.mockReturnValue('worked').
Verwenden Object.assign auf dem Mock-Konstruktor ermöglicht das gleichzeitige Mocking der Klasse und ihrer statischen Methoden. Auf diese Weise können Sie die gleiche Struktur erreichen, die Sie erhalten, wenn Sie eine Klasse mit statischen Membern erstellen.
import A from '../src/a'
import B from '../src/b'
jest.mock('../src/a', () =>
Object.assign(
jest.fn(
// constructor
() => ({
// mock instance here
f: jest.fn()
})),
{
// mock static here
staticF: jest.fn(),
}
)
)
Wir müssen einen Mock erstellen und der Testsuite Sichtbarkeit für die mockierte Methode geben. Unten vollständige Lösung mit Kommentaren.
let mockF; // here we make variable in the scope we have tests
jest.mock('path/to/StaticClass', () => {
mockF = jest.fn(() => Promise.resolve()); // here we assign it
return {staticMethodWeWantToMock: mockF}; // here we use it in our mocked class
});
// test
describe('Test description', () => {
it('here our class will work', () => {
ourTestedFunctionWhichUsesThisMethod();
expect(mockF).toHaveBeenCalled(); // here we should be ok
})
})