任何()与任何(Class.class)Mockito
any() vs any(Class.class) Mockito
我无法理解为什么下面的两个测试没有给出相同的结果。
@Service
public class SomeManager{
private final SomeDependency someDependency;
@Autowired
public SomeManager(SomeDependency someDependency){
this.someDependency = someDependency;
}
public List<returnType> methodToTest(Arg arg){
List<JsonObject> jo = someDependency.search(arg);
return jo.stream().map(returnType::parse).collect(Collectors.toList());
}
}
用 any()
测试。本次测试通过。
@RunWith(SpringJUnit4ClassRunner.class)
public class TestMethodToTest(){
@Test
public void TestMethod(){
SomeDependency someDependency = mock(SomeDependency.class);
List<JsonObject> expected := \some valid list of JsonObject\
// Here I used any() method.
when(someDependency.search(any())).thenReturn(expected);
SomeManager someManager = new SomeManager(someDependency);
List<returnType> actual = someManager.methodToTest(any(Arg.class));
assertArrayEquals(acutal.toArray(), expected.stream().map(returnType::parse).toArray());
}
}
但是由于 SomeDependency
的 search(Arg arg)
方法采用 class Arg
的参数,所以我将上面的测试更改为:
@RunWith(SpringJUnit4ClassRunner.class)
public class TestMethodToTest(){
@Test
public void TestMethod(){
SomeDependency someDependency = mock(SomeDependency.class);
List<JsonObject> expected := \some valid list of JsonObject\
// Here I used any(Arg.class) method.
when(someDependency.search(any(Arg.class))).thenReturn(expected);
SomeManager someManager = new SomeManager(someDependency);
List<returnType> actual = someManager.methodToTest(any(Arg.class));
assertArrayEquals(acutal.toArray(), expected.stream().map(returnType::parse).toArray());
}
}
第二次测试失败并输出 java.lang.AssertionError: array lengths differed, expected.length=1 actual.length=0
。这背后的可能原因是什么?
注意:输出中的值 expected.length=1
取决于用户提供的值作为测试中 json 对象的有效列表。
区别在于any
匹配null,而anyClass
不匹配null。见 ArgumentMatchers javadoc:
any()
匹配任何内容,包括空值和可变参数。
any(Class<T> type)
匹配给定类型的任何对象,不包括空值。
您正在将 null 传递给您在此处测试的方法:
List<returnType> actual = someManager.methodToTest(any(Arg.class));
any()
returns 您传递给被测方法的 null。
请注意,以这种方式使用参数匹配器是非法的 - 您只能在对 when
和 verify
的调用中调用它们。您应该将 Arg
的真实实例传递给被测方法。
Matcher methods like any(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null). This implementation is due to static type safety imposed by the java compiler. The consequence is that you cannot use any(), eq() methods outside of verified/stubbed method.
我无法理解为什么下面的两个测试没有给出相同的结果。
@Service
public class SomeManager{
private final SomeDependency someDependency;
@Autowired
public SomeManager(SomeDependency someDependency){
this.someDependency = someDependency;
}
public List<returnType> methodToTest(Arg arg){
List<JsonObject> jo = someDependency.search(arg);
return jo.stream().map(returnType::parse).collect(Collectors.toList());
}
}
用 any()
测试。本次测试通过。
@RunWith(SpringJUnit4ClassRunner.class)
public class TestMethodToTest(){
@Test
public void TestMethod(){
SomeDependency someDependency = mock(SomeDependency.class);
List<JsonObject> expected := \some valid list of JsonObject\
// Here I used any() method.
when(someDependency.search(any())).thenReturn(expected);
SomeManager someManager = new SomeManager(someDependency);
List<returnType> actual = someManager.methodToTest(any(Arg.class));
assertArrayEquals(acutal.toArray(), expected.stream().map(returnType::parse).toArray());
}
}
但是由于 SomeDependency
的 search(Arg arg)
方法采用 class Arg
的参数,所以我将上面的测试更改为:
@RunWith(SpringJUnit4ClassRunner.class)
public class TestMethodToTest(){
@Test
public void TestMethod(){
SomeDependency someDependency = mock(SomeDependency.class);
List<JsonObject> expected := \some valid list of JsonObject\
// Here I used any(Arg.class) method.
when(someDependency.search(any(Arg.class))).thenReturn(expected);
SomeManager someManager = new SomeManager(someDependency);
List<returnType> actual = someManager.methodToTest(any(Arg.class));
assertArrayEquals(acutal.toArray(), expected.stream().map(returnType::parse).toArray());
}
}
第二次测试失败并输出 java.lang.AssertionError: array lengths differed, expected.length=1 actual.length=0
。这背后的可能原因是什么?
注意:输出中的值 expected.length=1
取决于用户提供的值作为测试中 json 对象的有效列表。
区别在于any
匹配null,而anyClass
不匹配null。见 ArgumentMatchers javadoc:
any()
匹配任何内容,包括空值和可变参数。any(Class<T> type)
匹配给定类型的任何对象,不包括空值。
您正在将 null 传递给您在此处测试的方法:
List<returnType> actual = someManager.methodToTest(any(Arg.class));
any()
returns 您传递给被测方法的 null。
请注意,以这种方式使用参数匹配器是非法的 - 您只能在对 when
和 verify
的调用中调用它们。您应该将 Arg
的真实实例传递给被测方法。
Matcher methods like any(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null). This implementation is due to static type safety imposed by the java compiler. The consequence is that you cannot use any(), eq() methods outside of verified/stubbed method.