【发布时间】:2021-06-18 15:39:18
【问题描述】:
我一直在阅读一些文章,并在 Stack Overflow 上发布了关于何时应该模拟函数以及何时不应该模拟函数的帖子,但我有一个案例我不确定该怎么做。
我有一个 UserService 类,它使用依赖注入概念通过其构造函数接收依赖项。
class UserService {
constructor(userRepository) {
this.userRepository = userRepository;
}
async getUserByEmail(userEmail) {
// would perform some validations to check if the value is an e-mail
const user = await this.userRepository.findByEmail(email);
return user;
}
async createUser(userData) {
const isEmailInUse = await this.getUserByEmail(userData.email);
if(isEmailInUse) {
return "error";
}
const user = await this.userRepository.create(userData);
return user;
}
}
我想测试 createUser 方法是否正常工作,为了我的测试,我创建了一个假的 userRepository,它基本上是一个带有模拟方法的对象,我将在实例化 UserService 类时使用它
const UserService = require('./UserService.js');
describe("User Service tests", () => {
let userService;
let userRepository;
beforeEach(() => {
userRepository = {
findOne: jest.fn(),
create: jest.fn(),
}
userService = new UserService(userRepository);
});
afterEach(() => {
resetAllMocks();
});
describe("createUser", () => {
it("should be able to create a new user", async () => {
const newUserData = { name: 'User', email: 'user@test.com.br' }
const user = { id: 1, name: 'User', email: 'user@test.com.br' }
userRepository.create.mockResolvedValue(user);
const result = await userService.createUser();
expect(result).toStrictEqual(user);
})
})
})
请注意,在 createUser 方法中,调用了 getUserByEmail 方法,该方法也是 UserService 类的方法,这就是我感到困惑的地方。
我是否应该模拟 getUserByEmail 方法,即使它是我正在测试的类的方法?如果这不是正确的方法,我该怎么办?
【问题讨论】:
-
这个问题是相当基于意见的,但我想说只有模拟存储库才能让你的整个班级更容易测试。只有一件事要模拟,这样您可以检查您的类方法是否协同工作以提供预期的结果(当您尝试创建现有用户时返回
"error") -
@blex 我担心的是,如果 getUserByEmail 方法有一些错误,即使问题不在函数本身,createUser 测试也可能失败
-
总是视情况而定。您可以将它们视为不同的单元并单独测试,或者将它们视为一个并一起测试。由于您模拟了依赖项,因此这减少了移动部件的数量,因此即使问题不在函数本身,失败的风险也会降低。无论如何,您都可以监视某个方法以确保调用符合您的期望。
标签: javascript unit-testing jestjs mocking