Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.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_Mockito - Fatal编程技术网

Java 单元测试方法参数验证最佳实践

Java 单元测试方法参数验证最佳实践,java,unit-testing,mockito,Java,Unit Testing,Mockito,在单元测试时,用复杂参数验证方法调用的最佳实践是什么 假设我正在测试这样一个函数: class ClassA { ClassB dependency; void someFunction(SomeInputForA input) { // do some thing dependency.anotherFunction(differentInput); } } 我可以考虑两个选项来验证someFunction是否使用正确的输入调用anotherFunction:

在单元测试时,用复杂参数验证方法调用的最佳实践是什么

假设我正在测试这样一个函数:

class ClassA {
  ClassB dependency;

  void someFunction(SomeInputForA input) {
    // do some thing
    dependency.anotherFunction(differentInput);
  }
}
我可以考虑两个选项来验证
someFunction
是否使用正确的输入调用
anotherFunction

A) 对调用另一个函数的依赖项进行模拟验证

unitUnderTest.dependency = mockClassB;

InputClass expectedDifferentInput = ... ;

verify(mockClassB).anotherFunction(expectedDifferentInput);
B) 在调用另一个函数时执行参数捕获器,并断言属性

unitUnderTest.dependency = mockClassB;

ArgumentCaptor<InputClass> captor = ArgumentCaptor.for(InputClass.class);

verify(mockClassB).anotherFunction(captor.capture());

InputClass capturedInput = captor.getValue();
assertEquals(value, capturedInput.param1);
// and more asserts afterwards
unitUnderTest.dependency=mockClassB;
ArgumentCaptor captor=ArgumentCaptor.for(InputClass.class);
验证(mockClassB).另一个函数(captor.capture());
InputClass capturedInput=captor.getValue();
assertEquals(值、capturedInput.param1);
//之后还有更多的断言
这里有建议的路径吗?我倾向于captor方法,因为它感觉更为严格,并且不依赖于适当的对象


想法?

不同的输入是否被计算出来

如果是这样,那么您的B)是更好的方法,正如您对输入A所说的那样,您希望ClassA将其更改为expectedDifferentinInput,并希望验证是否调用了委托类(ClassB)。您正在验证ClassA的输入和委托逻辑的转换

如果differentInput与输入无关,那么您不需要使用captor,因为实际上您只是在检查委托


对于类A上的某个函数,任何公共调用方都不需要知道类B,因此可以说方法A)和方法B)实际上都是,在这种情况下,因此您也可以使用捕获器。当您将输入更改为某个函数时,如果从输入中计算出不同的输入,则捕捉器还可以帮助您识别边缘情况。

您始终可以对传递到mockClassB.anotherFunction()的对象使用匹配器。例如,如果要比较对象上的字段,可以编写:

Matcher<YourClass> yourMatcher = Matchers.hasProperty("yourProperty", Matchers.equals(whatever));
verify(mockClassB).anotherFunction(argThat(yourMatcher));
Matcher yourMatcher=Matchers.hasProperty(“yourProperty”,Matchers.equals(无论什么));
验证(mockClassB).另一个函数(argThat(yourMatcher));

我更喜欢这种方式,因为您可以共享匹配器的when和verify的语法,并且可以组合匹配器的任意组合。你只需要包含最新的mockito和hamcrest库就可以了。

我使用了参数捕捉器,但非常少。您遇到的最大问题是,这种方法会创建脆弱的单元测试。当他们对一个类做了一个小小的更改,然后发现自己在调用不应该受到影响的类时,在单元测试中苦苦挣扎时,没有人会感到高兴

也就是说,你必须最终确保打了正确的电话。但是如果你依赖于一个equals覆盖工作,那么你就依赖于这个类有一个equals方法可以工作,这是该类契约的一部分(并且在该类中进行了单元测试),这是合理的


所以,这就是为什么我会投票支持保持它的简单性,只使用verify。最后也是一样,但是您的单元测试不那么脆弱。

如果这些值是由该方法创建或管理的,我会捕获它们并断言它们。如果它们被传递,即作为一项服务,则a是合适的。