模拟静态问题 class 属性
Problems mocking static class property
我有一个 class 应该记录一些东西。记录器是这样定义的。
export class Logger {
public static client = ClientStrategy.create();
public async logSth(msg: string) {
params = {"testThing": msg};
await Logger.client.updateItem(params);
}
export class ClientStrategy {
public static create() {
return new DatabaseClient(); // not important here just a factory, with a method updateItem
}
}
我正试图在开玩笑的测试中嘲笑它。我正在尝试模拟此客户端策略并为此创建一个方法。但它并没有像我预期的那样工作。
jest.mock("./ClientStrategy");
const mockClientStrategy = jest.mocked(ClientStrategy, false);
describe("Logger", () => {
beforeEach(() => {
jest.spyOn(<any>mockDatabaseClientStrategy, "create").mockImplementation(() => {
return {
updateItem: () => {
return {}
}
};
});
});
it("should log sth", async () => {
const response = await Logger.logSth("testMsg");
expect(response).not.tobeUndefined();
});
});
但我无法读取未定义的 属性“logSth”。你能帮我我在这里做错了什么吗?我认为我的模拟应该可以正常工作,但不幸的是我为此未定义。
jest.mock()
和 jest.spyOn()
都可以。但是没有必要将它们一起用于您的情况。因此,让我们使用 jest.spyOn()
来解决您的问题。
由于 ClientStrategy.create
将在您导入 Logger
class 时执行,您需要在导入 Logger
之前添加对 ClientStrategy.create
的监视 class.
此外,logSth
方法是一个实例方法,而不是 class 方法。
例如
Logger.ts
:
import { ClientStrategy } from './ClientStrategy';
console.log('ClientStrategy.create: ', ClientStrategy.create);
export class Logger {
public static client = ClientStrategy.create();
public async logSth(msg: string) {
const params = { testThing: msg };
return Logger.client.updateItem(params);
}
}
Logger.test.ts
:
import { ClientStrategy } from './ClientStrategy';
// import { Logger } from './Logger';
describe('Logger', () => {
let mockClient;
let Logger: typeof import('./Logger').Logger;
beforeEach(async () => {
mockClient = {
updateItem: jest.fn(),
};
jest.spyOn(ClientStrategy, 'create').mockReturnValue(mockClient);
Logger = await import('./Logger').then((m) => m.Logger);
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should log sth', async () => {
mockClient.updateItem.mockResolvedValueOnce('fake value');
const logger = new Logger();
const response = await logger.logSth('testMsg');
expect(response).toEqual('fake value');
});
});
ClientStrategy.ts
:
export class ClientStrategy {
public static create() {
return { updateItem: async (params) => 'real value' };
}
}
测试结果:
PASS Whosebug/71938329/Logger.test.ts
Logger
✓ should log sth (22 ms)
console.log
ClientStrategy.create: [Function: mockConstructor] {
_isMockFunction: true,
getMockImplementation: [Function (anonymous)],
mock: [Getter/Setter],
mockClear: [Function (anonymous)],
mockReset: [Function (anonymous)],
mockRestore: [Function (anonymous)],
mockReturnValueOnce: [Function (anonymous)],
mockResolvedValueOnce: [Function (anonymous)],
mockRejectedValueOnce: [Function (anonymous)],
mockReturnValue: [Function (anonymous)],
mockResolvedValue: [Function (anonymous)],
mockRejectedValue: [Function (anonymous)],
mockImplementationOnce: [Function (anonymous)],
mockImplementation: [Function (anonymous)],
mockReturnThis: [Function (anonymous)],
mockName: [Function (anonymous)],
getMockName: [Function (anonymous)]
}
at Object.<anonymous> (Whosebug/71938329/Logger.ts:3:9)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.57 s, estimated 11 s
您可以取消注释import { Logger } from './Logger';
语句并注释import()
来检查日志。您将看到未模拟的 ClientStrategy.create
方法:
console.log
ClientStrategy.create: [Function: create]
我有一个 class 应该记录一些东西。记录器是这样定义的。
export class Logger {
public static client = ClientStrategy.create();
public async logSth(msg: string) {
params = {"testThing": msg};
await Logger.client.updateItem(params);
}
export class ClientStrategy {
public static create() {
return new DatabaseClient(); // not important here just a factory, with a method updateItem
}
}
我正试图在开玩笑的测试中嘲笑它。我正在尝试模拟此客户端策略并为此创建一个方法。但它并没有像我预期的那样工作。
jest.mock("./ClientStrategy");
const mockClientStrategy = jest.mocked(ClientStrategy, false);
describe("Logger", () => {
beforeEach(() => {
jest.spyOn(<any>mockDatabaseClientStrategy, "create").mockImplementation(() => {
return {
updateItem: () => {
return {}
}
};
});
});
it("should log sth", async () => {
const response = await Logger.logSth("testMsg");
expect(response).not.tobeUndefined();
});
});
但我无法读取未定义的 属性“logSth”。你能帮我我在这里做错了什么吗?我认为我的模拟应该可以正常工作,但不幸的是我为此未定义。
jest.mock()
和 jest.spyOn()
都可以。但是没有必要将它们一起用于您的情况。因此,让我们使用 jest.spyOn()
来解决您的问题。
由于 ClientStrategy.create
将在您导入 Logger
class 时执行,您需要在导入 Logger
之前添加对 ClientStrategy.create
的监视 class.
此外,logSth
方法是一个实例方法,而不是 class 方法。
例如
Logger.ts
:
import { ClientStrategy } from './ClientStrategy';
console.log('ClientStrategy.create: ', ClientStrategy.create);
export class Logger {
public static client = ClientStrategy.create();
public async logSth(msg: string) {
const params = { testThing: msg };
return Logger.client.updateItem(params);
}
}
Logger.test.ts
:
import { ClientStrategy } from './ClientStrategy';
// import { Logger } from './Logger';
describe('Logger', () => {
let mockClient;
let Logger: typeof import('./Logger').Logger;
beforeEach(async () => {
mockClient = {
updateItem: jest.fn(),
};
jest.spyOn(ClientStrategy, 'create').mockReturnValue(mockClient);
Logger = await import('./Logger').then((m) => m.Logger);
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should log sth', async () => {
mockClient.updateItem.mockResolvedValueOnce('fake value');
const logger = new Logger();
const response = await logger.logSth('testMsg');
expect(response).toEqual('fake value');
});
});
ClientStrategy.ts
:
export class ClientStrategy {
public static create() {
return { updateItem: async (params) => 'real value' };
}
}
测试结果:
PASS Whosebug/71938329/Logger.test.ts
Logger
✓ should log sth (22 ms)
console.log
ClientStrategy.create: [Function: mockConstructor] {
_isMockFunction: true,
getMockImplementation: [Function (anonymous)],
mock: [Getter/Setter],
mockClear: [Function (anonymous)],
mockReset: [Function (anonymous)],
mockRestore: [Function (anonymous)],
mockReturnValueOnce: [Function (anonymous)],
mockResolvedValueOnce: [Function (anonymous)],
mockRejectedValueOnce: [Function (anonymous)],
mockReturnValue: [Function (anonymous)],
mockResolvedValue: [Function (anonymous)],
mockRejectedValue: [Function (anonymous)],
mockImplementationOnce: [Function (anonymous)],
mockImplementation: [Function (anonymous)],
mockReturnThis: [Function (anonymous)],
mockName: [Function (anonymous)],
getMockName: [Function (anonymous)]
}
at Object.<anonymous> (Whosebug/71938329/Logger.ts:3:9)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.57 s, estimated 11 s
您可以取消注释import { Logger } from './Logger';
语句并注释import()
来检查日志。您将看到未模拟的 ClientStrategy.create
方法:
console.log
ClientStrategy.create: [Function: create]