我正在编写一个使用外部API的typeScript程序。在为该程序编写测试的过程中,我无法正确地模拟出对外部API的依赖性,从而无法检查传递给API本身的值。
命中该API的代码的简化版本如下:
const api = require("api-name")();
export class DataManager {
setup_api = async () => {
const email = "email@website.ext";
const password = "password";
try {
return api.login(email, password);
} catch (err) {
throw new Error("Failure to log in: " + err);
}
};
我的测试逻辑如下:
jest.mock("api-name", () => () => {
return {
login: jest.fn().mockImplementation(() => {
return "200 - OK. Log in successful.";
}),
};
});
import { DataManager } from "../../core/dataManager";
const api = require("api-name")();
describe("DataManager.setup_api", () => {
it("should login to API with correct parameters", async () => {
//Arrange
let manager: DataManager = new DataManager();
//Act
const result = await manager.setup_api();
//Assert
expect(result).toEqual("200 - OK. Log in successful.");
expect(api.login).toHaveBeenCalledTimes(1);
});
});
我感到困惑的是,失败的测试断言只是expect(api.login).toHaveBeenCalledTimes(1)
。这意味着该API已被模拟,但我无权访问原始模拟。我认为这是因为测试逻辑的开头是在调用时用新的login
来代替jest.fn()
。不管这是真的,我不知道如何防止它或无法访问模拟函数,这是我想做的,因为我更关心的是用正确的值调用该函数,而不是返回特定的值。 / p>
我认为模拟该库的困难与它的导入方式有关:const api = require("api-name")();
,在require语句之后,必须在其中加上一个左括号和右括号。但是我并不完全知道这意味着什么,或者它意味着重新测试。
答案 0 :(得分:0)
我在this issue thread中碰到了ts-jest的答案。显然,ts-jest不会像常规的玩笑一样“提升”遵循命名模式mock*
的变量。结果,当您尝试为factory
使用jest.mock()
参数之前实例化命名的模拟变量时,会收到一个错误,指出您无法在初始化之前访问该模拟变量。
对于每个前面提到的线程,jest.doMock()
方法的工作方式与jest.mock()
相同,不同之处在于它没有“提升”到文件的顶部。因此,您可以在模拟库之前创建变量。
因此,一种可行的解决方案如下:
const mockLogin = jest.fn().mockImplementation(() => {
return "Mock Login Method Called";
});
jest.doMock("api-name", () => () => {
return {
login: mockLogin,
};
});
import { DataManager } from "../../core/dataManager";
describe("DataManager.setup_api", () => {
it("should login to API with correct parameters", async () => {
//Arrange
let manager: DataManager = new DataManager();
//Act
const result = await manager.setup_api();
//Assert
expect(result).toEqual("Mock Login Method Called");
expect(mockLogin).toHaveBeenCalledWith("email@website.ext", "password");
});
});
同样,这仅在使用ts-jest
时才有意义,因为使用babel
转换笑话打字稿测试将支持正确的举升行为。将来,随着ts-jest
的更新,这种情况可能会有所变化,但是jest.doMock()
的解决方法暂时看来还不错。