java - 使用 Mockito 和 JUnit 进行测试时的奇怪行为

标签 java unit-testing junit mocking mockito

这里我正在测试 TestedClass 中带有签名的方法:

public static boolean getBoolean(ClassA classA);

这是我的模拟对象配置。

@Mock
private ClassA mockedCLass;  //I try to mock ClassA behaviour

.....

when(mockedClass.getValues()).thenReturn(null,emptyList,oneElementList,defaultList);

getBoolean() 方法使用模拟对象。不幸的是,当我使用这种方法时,模拟的行为似乎完全错误。

boolean res1 = TestedClass.getBoolean(mockedClass);
boolean res2 = TestedClass.getBoolean(mockedClass);
boolean res3 = TestedClass.getBoolean(mockedClass);
boolean res4 = TestedClass.getBoolean(mockedClass);

但是当我这样拆分时:

when(mockedClass.getValues()).thenReturn(null);
boolean res1 = TestedClass.getBoolean(mockedClass);

when(mockedClass.getValues()).thenReturn(emptyList);
boolean res2 = TestedClass.getBoolean(mockedClass);

等等,一切都很好。这里发生了什么?如果有任何帮助,我将不胜感激。

编辑: //测试用例

List<String> emptyList = Collections.<String>emptyList();
List<String> defaultList = Arrays.asList("one", "two", "three");
List<String> oneElementList = Arrays.asList("one");

这是来自 TestedClass 的 boolean 方法示例。

 public static boolean getBoolean(ClassA classA){
 return classA.getValues() == null || classA.getValues().size() <= 1; }

当我调用第一种方法的测试用例时,我得到:

1)null,defaultList,oneElementList -> true,true,true instead of true,false,true
2)oneElementList,null,defaultList -> error, Null pointer exception
3)null,oneElementList,defaultList,emptyList -> true,false,true,true instead of true,true,false,true
4)null or defaultList or oneElementList or emptyList -> works fine for one case

最佳答案

在您的 getBoolean 方法中

public static boolean getBoolean(ClassA classA) {
    return classA.getValues() == null || classA.getValues().size() <= 1;
}

您调用了 stub 方法两次。每次调用都会消耗提供给 thenReturn 的一个值,直到最后一个值,然后重复该值。

您可能希望提取一次 getValues 的结果并重复使用它。

public static boolean getBoolean(ClassA classA) {
    List<String> values = classA.getValues();
    return values == null || values.size() <= 1;
}

Rogério在评论中建议,最好将测试限制在不同的场景中,即。每个输入值一个。这与第二种方法中发生的情况类似。每个测试都会为调用 getValues 生成自己的 stub ,而不会干扰其他测试。

您需要对 null 参数进行一项测试,一项针对空列表,一项针对包含一个元素的列表,一项针对包含多个元素的列表。例如

@Test
public void nullArgument() {
    when(mockedClass.getValues()).thenReturn(null);
    Assert.assertTrue(TestedClass.getBoolean(mockedClass));
}
@Test
public void emptyListArgument() {
    List<String> emptyList = Collections.<String>emptyList();
    when(mockedClass.getValues()).thenReturn(emptyList);
    Assert.assertTrue(TestedClass.getBoolean(mockedClass));
}

等等。

关于java - 使用 Mockito 和 JUnit 进行测试时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37970798/

相关文章:

java - 使用 ServerSocket 类对方法进行单元测试的最佳方法是什么?

java - 实现 jframe 类的接口(interface)

java - 如何绕过 java.nio.file.DirectoryNotEmptyException?

java - 如何在没有服务器的情况下测试我的 Struts 1.2 Web 应用程序?

entity-framework - 实现存储库模式并进行测试

java - 使用 Apache Ant 构建成功但未运行 junit 文件

java - Powermock - java.lang.IllegalStateException : Failed to transform class

java - 如何在 Java 中取消 Files.copy()?

java - 如何在 RecyclerView 中使用 CountDownTimer?

java.lang.IllegalStateException 尝试使用 randoop 生成单元测试