Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.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
Spring boot 使用MockitoJunitRunner进行单元测试:对于任何(…)匹配器,return始终返回null_Spring Boot_Mockito_Junit4 - Fatal编程技术网

Spring boot 使用MockitoJunitRunner进行单元测试:对于任何(…)匹配器,return始终返回null

Spring boot 使用MockitoJunitRunner进行单元测试:对于任何(…)匹配器,return始终返回null,spring-boot,mockito,junit4,Spring Boot,Mockito,Junit4,使用Spring Boot 2.1.6.0版本发布。在使用MockitoJunitRunner进行的单元测试中,我模拟了一个REST控制器,如下所示: @Mock private MyController myController; when (myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class))).thenReturn(new ResponseEntity<MyOutput

使用Spring Boot 2.1.6.0版本发布。在使用MockitoJunitRunner进行的单元测试中,我模拟了一个REST控制器,如下所示:

  @Mock
  private MyController myController;
when (myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class))).thenReturn(new ResponseEntity<MyOutputDto>(myOutputDto, HttpStatus.OK));
然后,我将端点调用的预期定义如下:

  @Mock
  private MyController myController;
when (myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class))).thenReturn(new ResponseEntity<MyOutputDto>(myOutputDto, HttpStatus.OK));
when(myController.myEndpoint(any(MyInputDto.class)、any(OAuth2Authentication.class))。然后返回(newresponseEntity(myOutputDto,HttpStatus.OK));
但以下呼吁:

ResponseEntity<MyOutputDto> resp = myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class));
assertNotNull(resp);
ResponseEntity resp=myController.myEndpoint(any(MyInputDto.class)、any(OAuth2Authentication.class));
资产不为空(resp);
当resp为null时引发java.lang.AssertionError。为什么呢?当然,这两个参数在when(…)子句和调用之间是不同的实例(可能都是null),但我的理解是,它们不必匹配,因为我使用的是任何(…)匹配器,这意味着无论这些实例是什么,返回都应该是相同的


这里我缺少什么?

当使用两个参数调用其
myEndpoint
方法时,您定义了模拟对象以返回一个新的
ResponseEntity
:类型为
MyInputDto
的任何对象和类型为
OAuth2Authentication
的任何对象

但是当您实际使用

ResponseEntity<MyOutputDto> resp = myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class));
可以工作,但这并不能提供您希望通过运行模拟测试实现的目标:它只会检查模拟是否返回您定义的内容,但不会测试您的控制器行为


你应该做的是:

不要嘲笑你想要测试的类;模拟其依赖关系。

private MyController myController;

@Mock
private MyInputDto inputDto;
@Mock
private OAuth2Authentication authentication;

// mock all method calls that are needed on dependencies
when(inputDto.someMethod(...)).thenReturn(...);
[...]
when(authentication.someMethod(...)).thenReturn(...);
[...]
现在,您可以测试测试对象的实际行为:

ResponseEntity<MyOutputDto> resp = myController.myEnpoint(inputDto, authentication);
assertNotNull(resp);
ResponseEntity resp=myController.myEnpoint(输入到,身份验证);
资产不为空(resp);
很好的Mockito教程:


Mockito甚至在试图实现测试时暗示出一些错误,就像你在问题中所做的那样。运行你的测试,我得到

[MockitoHint]MockitoTest.test(有关MockitoHint,请参阅javadoc):

[模仿提示]1。未使用…->在MockitoTest.test(MockitoTest.java:24)

[模拟提示]…参数是否正常?->在MockitoTest.test(MockitoTest.java:26)

第24行是指mock被存根的那一行(when(…).thenReturn()部分),因为它从未被使用过;第26行引用调用行,因为它使用匹配器而不是对象


运行测试时,您应该会在控制台上看到类似的输出。

当使用两个参数调用模拟对象的
myEndpoint
方法时,您定义了模拟对象以返回新的
响应属性
:类型为
MyInputDto
的任何对象和类型为
OAuth2Authentication
的任何对象

但是当您实际使用

ResponseEntity<MyOutputDto> resp = myController.myEndpoint(any(MyInputDto.class), any(OAuth2Authentication.class));
可以工作,但这并不能提供您希望通过运行模拟测试实现的目标:它只会检查模拟是否返回您定义的内容,但不会测试您的控制器行为


你应该做的是:

不要嘲笑你想要测试的类;模拟其依赖关系。

private MyController myController;

@Mock
private MyInputDto inputDto;
@Mock
private OAuth2Authentication authentication;

// mock all method calls that are needed on dependencies
when(inputDto.someMethod(...)).thenReturn(...);
[...]
when(authentication.someMethod(...)).thenReturn(...);
[...]
现在,您可以测试测试对象的实际行为:

ResponseEntity<MyOutputDto> resp = myController.myEnpoint(inputDto, authentication);
assertNotNull(resp);
ResponseEntity resp=myController.myEnpoint(输入到,身份验证);
资产不为空(resp);
很好的Mockito教程:


Mockito甚至在试图实现测试时暗示出一些错误,就像你在问题中所做的那样。运行你的测试,我得到

[MockitoHint]MockitoTest.test(有关MockitoHint,请参阅javadoc):

[模仿提示]1。未使用…->在MockitoTest.test(MockitoTest.java:24)

[模拟提示]…参数是否正常?->在MockitoTest.test(MockitoTest.java:26)

第24行是指mock被存根的那一行(when(…).thenReturn()部分),因为它从未被使用过;第26行引用调用行,因为它使用匹配器而不是对象


运行测试时,您应该会在控制台上看到类似的输出。

为什么要使用匹配器调用端点?您应该创建一个
MyInputDto
和身份验证(或模拟它们)并通过它们,而不是使用匹配器。@M.Deinum:因为这是一个完美的合法操作,没有理由不这样做。而且还因为OAuth2Authentication对象既不能实例化也不能模拟。这些是匹配器而不是对象。为什么您不能模拟
OAuth2Authentication
。这在
Mockito.mock(您的类在这里>)中是完全可行的
正如@M.Deinum已经说过的,在调用模拟对象时不应该使用匹配器。改用实际对象:MyInputDto和OAuth2Authentication的实例。但是所要做的只是测试您的模拟是否有效,而不是测试您的方法调用是否对要测试的对象有效。您可能不想模拟您的控制器,但其他对象是M.Deinum编写的。(暂时不作为答案发布,我不知道你想在这里做什么。)
any
mather的行为完全符合他们应该做的。问题是,在调用实际方法时也使用了matchers,这是不应该做的事情。正如@ModusTollens所正确观察到的,您的测试实际上没有测试任何东西,它测试的是模拟而不是控制器。如果你想测试你的控制器,你应该模拟它的依赖关系,而不是控制器本身。你为什么要用匹配器调用端点?您应该创建一个
MyInputDto
和身份验证(或模拟它们)并通过它们,而不是使用匹配器。@M.Deinum:因为这是一个完美的合法操作,没有理由不这样做。而且还因为OAuth2Authentication对象既不能实例化也不能模拟。这些是匹配器而不是对象。为什么您不能模拟
OAuth2Authentication
。这在
Mockito.mock(您的类在这里>)中是完全可行的
正如@M.Deinum已经说过的,在调用模拟对象时不应该使用匹配器