[英]Mocking up static methods in jest
我在開玩笑的 static 方法上遇到了麻煩 mocking。 想象一下你有一個 class A 和一個 static 方法:
export default class A {
f() {
return 'a.f()'
}
static staticF () {
return 'A.staticF()'
}
}
和一個進口A的class B
import A from './a'
export default class B {
g() {
const a = new A()
return a.f()
}
gCallsStaticF() {
return A.staticF()
}
}
現在你想模擬 A。模擬 f() 很容易:
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()'
})
})
但是,我找不到任何關於如何模擬 A.staticF 的文檔。 這可能嗎?
您可以將模擬分配給靜態方法
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')
})
})
希望對你有幫助
// code to mock
export class AnalyticsUtil {
static trackEvent(name) {
console.log(name)
}
}
// mock
jest.mock('../src/AnalyticsUtil', () => ({
AnalyticsUtil: {
trackEvent: jest.fn()
}
}))
// code to mock
export default class Manager {
private static obj: Manager
static shared() {
if (Manager.obj == null) {
Manager.obj = new Manager()
}
return Manager.obj
}
nonStaticFunc() {
}
}
// mock
jest.mock('../src/Manager', () => ({
shared: jest.fn().mockReturnValue({
nonStaticFunc: jest.fn()
})
}))
// usage in code
someFunc() {
RNDefaultPreference.set('key', 'value')
}
// mock RNDefaultPreference
jest.mock('react-native-default-preference', () => ({
set: jest.fn()
}))
// code to mock
export namespace NavigationActions {
export function navigate(
options: NavigationNavigateActionPayload
): NavigationNavigateAction;
}
// mock
jest.mock('react-navigation', () => ({
NavigationActions: {
navigate: jest.fn()
}
}))
我設法使用原型在__mocks__
文件夾中的一個單獨文件中模擬它。 所以你會這樣做:
function A() {}
A.prototype.f = function() {
return 'a.f()';
};
A.staticF = function() {
return 'A.staticF()';
};
export default A;
我們需要創建一個模擬並將模擬方法的可見性提供給測試套件。 以下帶有評論的完整解決方案。
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
})
})
我選擇了使用jest.spyOn
的路線。
encryption.ts
export class Encryption {
static encrypt(str: string): string {
// ...
}
static decrypt(str: string): string {
// ...
}
}
property-encryption.spec.ts
import { Encryption } from './encryption'
import { PropertyEncryption } from './property-encryption'
describe('PropertyEncryption', () => {
beforeAll(() => {
jest
.spyOn(Encryption, 'encrypt')
.mockImplementation(() => 'SECRET')
jest
.spyOn(Encryption, 'decrypt')
.mockImplementation(() => 'No longer a secret')
})
it("encrypts object values and retains the keys", () => {
const encrypted = PropertyEncryption.encrypt({ hello: 'world' });
expect(encrypted).toEqual({ hello: 'SECRET' });
});
it("decrypts object values", () => {
const decrypted = PropertyEncryption.decrypt({ hello: "SECRET" });
expect(decrypted).toEqual({ hello: 'No longer a secret' });
});
})
在模擬構造函數上使用Object.assign
允許同時模擬類及其靜態方法。 這樣做可以讓您獲得與創建具有靜態成員的類時相同的結構。
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(),
}
)
)
這是一個 ES6 導入的示例。
import { MyClass } from '../utils/my-class';
const myMethodSpy = jest.spyOn(MyClass, 'foo');
describe('Example', () => {
it('should work', () => {
MyClass.foo();
expect(myMethodSpy).toHaveBeenCalled();
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.