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 使用“verify”显式检查函数调用参数,或使用“when”隐式检查函数调用参数?_Java_Unit Testing_Testing_Mockito - Fatal编程技术网

Java 使用“verify”显式检查函数调用参数,或使用“when”隐式检查函数调用参数?

Java 使用“verify”显式检查函数调用参数,或使用“when”隐式检查函数调用参数?,java,unit-testing,testing,mockito,Java,Unit Testing,Testing,Mockito,使用Mockito检查正确参数是否位于正确位置的最佳方法是什么 考虑下一个单元测试: @Test public void getProjectByIdTest() { Long projectId = 1L; ProjectEntity expectedProject = mock(ProjectEntity.class); when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

使用
Mockito
检查正确参数是否位于正确位置的最佳方法是什么

考虑下一个单元测试:

@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);
    when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));
    verify(projectRepository).findOne(projectId);
}
@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);
    when(projectRepository.findOne(projectId)).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));
}
这里我们检查
projectService
是否使用
verify
显式地将其参数传递到正确的位置

现在检查此单元测试:

@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);
    when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));
    verify(projectRepository).findOne(projectId);
}
@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);
    when(projectRepository.findOne(projectId)).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));
}
它还检查
projectService
是否将其参数传递到了正确的位置,但在
时隐式地传递了
(因此,如果
projectService
实际将一些随机数传递到
projectRepository.findOne()
断言
将失败,因为mock将返回错误的值)


那么这应该怎么做呢?在我看来,如果没有
verify
,这个测试就会失去一些清晰性;但是从另一方面来说,它的长度更短。

UnitTest的第三个最重要的事情是可读性,这是在由于正确的原因失败并且速度很快之后


测试的读者应该很容易理解测试失败的原因。因此,将您的模拟配置为尽可能宽容,并检查验证中的行为。

UnitTest由于正确的原因失败且速度快后,第三个最重要的事情是可读性


测试的读者应该很容易理解测试失败的原因。因此,将您的模拟配置为尽可能宽容,并检查验证中的行为。

请注意。您的mockito行为记录在两个示例之间并不对称:

when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

在这两种情况下,您都应该使用
when(projectRepository.findOne(projectd))
来查看您如何进行断言

那么这应该怎么做呢?在我看来,没有这一点 这个测试失去了一些清晰度;但从另一方面看,它较短

个人认为,当我想模拟的方法没有返回类型时,将代码> Valuy()<代码>作为一个降级的解决方案。 在某些情况下,它至少允许检查是否调用了依赖项以及依赖项所具有的预期参数。

如果模拟依赖项的方法返回了一些东西,就像在您的案例中一样,那么从单元测试的角度来看,第二种解决方案似乎更自然

当你这样写的时候:

when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);
assertThat(projectService.getById(projectId), is(expectedProject));
verify(projectRepository).findOne(projectId);
您给人的印象是,您希望模拟依赖项存储库,但还希望检查存储库中每个被调用的方法

首先,它是多余的,因为如果 这个断言是正确的:
assertThat(projectService.getById(projectId),is(expectedProject)),这意味着已使用预期参数调用存储库,并已返回预期项目。为什么要用
verify(projectRepository).findOne(projectd)再次检查它


其次,单元测试的目标不是检查依赖项上的每个方法是否被调用。它不会带来很多断言方面的东西,您将单元测试与依赖项的api紧密结合,从而使测试变得更加复杂

少说话。您的mockito行为记录在两个示例之间并不对称:

when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

在这两种情况下,您都应该使用
when(projectRepository.findOne(projectd))
来查看您如何进行断言

那么这应该怎么做呢?在我看来,没有这一点 这个测试失去了一些清晰度;但从另一方面看,它较短

个人认为,当我想模拟的方法没有返回类型时,将代码> Valuy()<代码>作为一个降级的解决方案。 在某些情况下,它至少允许检查是否调用了依赖项以及依赖项所具有的预期参数。

如果模拟依赖项的方法返回了一些东西,就像在您的案例中一样,那么从单元测试的角度来看,第二种解决方案似乎更自然

当你这样写的时候:

when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);
assertThat(projectService.getById(projectId), is(expectedProject));
verify(projectRepository).findOne(projectId);
您给人的印象是,您希望模拟依赖项存储库,但还希望检查存储库中每个被调用的方法

首先,它是多余的,因为如果 这个断言是正确的:
assertThat(projectService.getById(projectId),is(expectedProject)),这意味着已使用预期参数调用存储库,并已返回预期项目。为什么要用
verify(projectRepository).findOne(projectd)再次检查它

其次,单元测试的目标不是检查依赖项上的每个方法是否被调用。它不会带来很多断言方面的东西,您将单元测试与依赖项的api紧密结合,从而使测试变得更加复杂

你想测试什么?您应该尝试测试您的测试单元(这里是您的测试方法)是否工作,并且只验证对该总合同很重要的交互

@Test
public void getProjectByIdTest_withVerify() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);

    // Your simulated dependency returns expectedProject for every ID?
    when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));

    // Is it a requirement of your test that this method must be called?
    // Maybe your system someday calls a "findAll" method, or caches values.
    verify(projectRepository).findOne(projectId);
}
比较:

@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);

    // You return the expectedProject when asked for. Everything else returns null.
    when(projectRepository.findOne(projectId)).thenReturn(expectedProject);

    // You check that the return value is correct, which implies the call succeeded.    
    assertThat(projectService.getById(projectId), is(expectedProject));
}
verify
交互肯定有自己的位置,特别是对于ArgumentCaptor和特定方法调用是合同一部分的交互,例如服务器或RPC调用或void方法调用

要获得真正权威的观点,请阅读Mockito创始人Szczepan Faber的文章。它提供了很多细节和见解,说明了从期望中可以推断出什么,哪些是值得验证的。

您想测试什么?您应该尝试测试您的测试单元(这里是您的测试方法)是否工作,并且只验证对该总合同很重要的交互

@Test
public void getProjectByIdTest_withVerify() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);

    // Your simulated dependency returns expectedProject for every ID?
    when(projectRepository.findOne(anyLong())).thenReturn(expectedProject);

    assertThat(projectService.getById(projectId), is(expectedProject));

    // Is it a requirement of your test that this method must be called?
    // Maybe your system someday calls a "findAll" method, or caches values.
    verify(projectRepository).findOne(projectId);
}
比较:

@Test
public void getProjectByIdTest() {
    Long projectId = 1L;
    ProjectEntity expectedProject = mock(ProjectEntity.class);

    // You return the expectedProject when asked for. Everything else returns null.
    when(projectRepository.findOne(projectId)).thenReturn(expectedProject);

    // You check that the return value is correct, which implies the call succeeded.    
    assertThat(projectService.getById(projectId), is(expectedProject));
}
verify
交互肯定有自己的位置,特别是对于ArgumentCaptor和特定方法调用是合同一部分的交互,例如服务器或RPC调用或void方法调用


要获得真正权威的观点,请阅读Mockito创始人Szczepan Faber的文章。它提供了许多细节和见解,说明了从期望中可以推断出什么与哪些值得验证。

谢谢,我喜欢你的推理!我把它编码成不对称的