gpt4 book ai didi

java - 努力应对单元测试和模拟

转载 作者:太空宇宙 更新时间:2023-11-04 15:20:37 26 4
gpt4 key购买 nike

我正在尝试模拟以下方法:

public void add(Question question) {
String username = authenticationManager.getUsername();
Candidate candidate = userService.getByUsername(username);

if (!authenticationManager.hasPermission("ROLE_ADMIN")) {
question.setStatus(QuestionStatus.WAITING);
}

question.setCandidate(candidate);
questionRepository.add(question);
}

这是我的尝试:

@Test
public void add_savesQuestionWithStatusWaiting_whenSubmittedAsUser() {
Candidate candidate = new Candidate();
Question question = mock(Question.class);

when(authenticationManager.getUsername()).thenReturn("andreas");
when(userService.getByUsername("andreas")).thenReturn(candidate);
when(authenticationManager.hasPermission("ROLE_ADMIN")).thenReturn(true);

questionService.add(question);
verify(question, times(0)).setStatus(any(QuestionStatus.class));
}

我想做的是测试应用程序逻辑。当用户没有 ROLE_ADMIN 时,问题状态将设置为等待。我的 mock 正确吗?

最佳答案

在单元测试中,您模拟不属于被测试单元的每个依赖项。 在您的情况下,您的单元是 QuestionRepository,并且您正在尝试测试对象上的所有预期交互是否发生,但不是在真实对象上而是在其模拟版本上发生。这是非常好的和自然的方法。

所以就如何使用mockito而言,你做得相当不错。不好的是 QuestionService.add 做得太多了。 “add”表明它将一些对象放入容器中,而不是其他任何东西。相反,它还进行复杂的问题对象设置。换句话说,它有副作用。结果是您必须测试的不同边界条件的数量很大。这将使您的测试将来难以维护。看看您必须创建多少个模拟。

如果你在一段时间后回到你的测试,你会尝试弄清楚它在做什么,这会很简单吗?我还认为测试名称并没有反射(reflect)实际测试的内容。对我来说,“add_savesQuestionWithStatusWaiting_whenSubscribedAsUser”意味着我应该期望在最后保存问题并将状态设置为“等待”,而不是使用验证来检查是否没有调用 setStatus()。

我会尝试重构 add 方法代码,因此它所做的只是将元素插入到 queryService 中。然后我将测试 QuestionService 的不同边界条件(例如,当提供 null 时它将如何表现)。我还将问题的设置移至应用程序的不同层,并在不同的单元中进行测试。

关于java - 努力应对单元测试和模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20431961/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com