java - IllegalStateException - 没有最后一次调用可用的模拟

标签 java junit easymock illegalstateexception

我正在尝试使用 EasyMock 来测试某个方法是否运行了特定次数,但我一直收到 IllegalStateException 错误,我不明白为什么。我是 EasyMock 和 JUnit 的新手,不太熟悉如何使用它们,所以我不确定自己做错了什么。

我的代码是:

FileOutputStream mockWriter;
Numbers mockByte;
@Test
public void testNumbers() throws IOException{   
    mockWriter = createMock(FileOutputStream.class);
    mockByte = new Numbers(mockWriter);
    mockByte.initByte();
    expect(mockByte.generate()).times(10000);
    replay(mockWriter);
}

这些是从我的 Numbers 类生成的方法 initByte 和 generate:

public void initByte() throws IOException{  
    File outFile = new File("NumbersOutput.txt");
    FileOutputStream f = new FileOutputStream(outFile);
    for(int i = 0; i < 10000; i++){
        int b = generate();
        f.write(b);
    }   
    f.flush();
    f.close();  
}

public int generate(){
    return rand.nextInt(100001);
}

最佳答案

你得到的错误是因为你的模拟没有调用任何东西。

与您的命名相反,mockByte 根本不是指模拟,因此在这样的 expect 调用中使用它不会帮助您。如果有的话,您应该期待对 mockWriter 的调用。

但是,您根本不清楚为什么要对流使用模拟,也不清楚 Numbers 构造函数中的 OutputStream 有何用途。除了 rand 之外,您的 initByte() 方法不使用对象内的任何状态。即使它已修复,使用 ByteArrayOutputStream 可能也是最简单的...让您的 API 使用 OutputStream 而不是 FileOutputStream 进行对话,这样测试起来会容易得多。

我猜你应该:

  • initByte 方法中移除新的 FileOutputStream 的构造,而是写入您在 Numbers 构造函数中接受的流
  • 如果您的构造函数参数类型是 FileOutputStream,请将其更改为 OutputStream 以使其更清晰且更易于测试
  • 在您的测试中创建一个 ByteArrayOutputStream - 您根本不需要模拟。然后您可以获得所有已写入的字节,并根据需要检查它们。
  • 仔细考虑您希望f.write(b) 做什么。它只会写入一个字节,因此您的随机数的前 24 位将被忽略。到那时,您为什么还要选择 [0, 10000] 范围内的数字?

关于java - IllegalStateException - 没有最后一次调用可用的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23613247/

相关文章:

java - 如何在一个大项目中找到 main() 函数

java - 如果 Java 版本为 1.5 或 1.6,则 ant 构建失败

java - 如何高效更新表的列值?

java - jUnit 测试精神

java - 如何用jUnit声明数据库列的Grails Controller 更新?

java - 什么是 Mockito 等价于 expect().andReturn().times()

java - Easymock 部分模拟(EasyMock ClassExtension),好还是坏?

java - 汉诺塔,停止滑动

file - 如何使用公共(public) Gradle API 创建临时文件/文件夹?

java - PowerMock - 如何调用操作模拟方法的参数