【问题标题】:IllegalStateException - no last call on a mock availableIllegalStateException - 没有可用的模拟最后一次调用
【发布时间】:2014-05-12 15:36:43
【问题描述】:

我正在尝试使用 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);
}

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

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);
}

【问题讨论】:

    标签: java junit easymock illegalstateexception


    【解决方案1】:

    您遇到的错误是因为在您的模拟上没有调用任何内容。

    与您的命名相反,mockByte 根本不指代模拟,因此像这样在 expect 调用中使用它对您没有帮助。你应该期待mockWriter 的来电(如果有的话)。

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

    我怀疑你应该:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多