Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 与单元测试和模拟作斗争_Java_Unit Testing_Mocking - Fatal编程技术网

Java 与单元测试和模拟作斗争

Java 与单元测试和模拟作斗争,java,unit-testing,mocking,Java,Unit Testing,Mocking,我试图模仿以下方法: public void add(Question question) { String username = authenticationManager.getUsername(); Candidate candidate = userService.getByUsername(username); if (!authenticationManager.hasPermission("ROLE_ADMIN")) {

我试图模仿以下方法:

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));
}

我试图做的是测试应用程序逻辑。当用户没有角色_ADMIN时,问题状态将设置为等待。我做的模拟对吗?

在单元测试中,你模拟了不是被测试单元一部分的每个依赖项。 在您的例子中,您的单元是questionRepository,您正在尝试测试对象上的所有预期交互是否都发生,而不是发生在真实对象上,而是发生在它们的模拟版本上。这是一种完美而自然的方法

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

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


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

你的测试结果是什么?@Luke我在寻找一个答案,说这是正确的方法还是错误的方法。我不确定我是否理解正确。测试通过了。你也可以做验证(问题);验证无交互作用(问题);问题服务添加方法是我的服务层中的一个bean。我不明白我是如何将这些逻辑转移到其他地方的?在阅读了几遍答案之后,我已经阅读/编写了更多的代码,我理解了你的意思。