Java IllegalStateException - 没有可用的模拟的最后一次调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23613247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IllegalStateException - no last call on a mock available
提问by user3629115
I'm trying to use EasyMock to test that a method runs a specific number of times but I keep getting an IllegalStateException error and I don't understand why. I'm new to EasyMock and JUnit and not very familiar with how to use them so I'm not sure what I'm doing wrong.
我正在尝试使用 EasyMock 来测试方法运行特定次数,但我不断收到 IllegalStateException 错误,我不明白为什么。我是 EasyMock 和 JUnit 的新手,对如何使用它们不是很熟悉,所以我不确定我做错了什么。
My code is:
我的代码是:
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);
}
And these are the methods initByte and generate from my Numbers class:
这些是 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);
}
回答by Jon Skeet
The error you're getting is because nothing's calling anything on your mock.
你得到的错误是因为没有任何东西在你的模拟上调用任何东西。
Contrary to your naming, mockByte
doesn't refer to a mock at all, so using it in an expect
call like this is not going to help you. You should be expecting calls on mockWriter
if anything.
与您的命名相反,mockByte
根本不涉及模拟,因此在这样的expect
调用中使用它对您没有帮助。mockWriter
如果有的话,您应该期待来电。
However, it's not clear why you're using a mock for a stream at all, nor what the OutputStream in the Numbers constructor is used for. Your initByte() method doesn't use any state within the object other than rand. Even when that's fixed, it would probably be simplest just to use a ByteArrayOutputStream... make your API talk in terms of OutputStream instead of FileOutputStream, and it'll be much easier to test.
但是,不清楚为什么要对流使用模拟,也不清楚 Numbers 构造函数中的 OutputStream 用于什么。您的 initByte() 方法不使用除 rand 之外的对象内的任何状态。即使问题已解决,使用 ByteArrayOutputStream 也可能是最简单的……让您的 API 使用 OutputStream 而不是 FileOutputStream,并且测试会容易得多。
I suspect you should:
我怀疑你应该:
- Remove the construction of a new
FileOutputStream
from theinitByte
method, instead writing to the stream you accept in theNumbers
constructor - If your constructor parameter type is
FileOutputStream
, change it toOutputStream
to make it cleaner and easier to test - Create a
ByteArrayOutputStream
in your test - you don't need mocking at all. You can then get all the bytes that have been written, and check them for whatever you want. - Think carefully about what you expect
f.write(b)
to do. It's only going to write a single byte, so the top 24 bits of your random number are going to be ignored. At that point, why are you choosing a number in the range [0, 10000] anyway?
FileOutputStream
从initByte
方法中删除 new 的构造,而不是写入您在Numbers
构造函数中接受的流- 如果您的构造函数参数类型是
FileOutputStream
,请将其更改为OutputStream
以使其更清晰且更易于测试 ByteArrayOutputStream
在您的测试中创建一个- 您根本不需要嘲笑。然后,您可以获取已写入的所有字节,并根据需要检查它们。- 仔细考虑你希望
f.write(b)
做什么。它只会写入一个字节,因此随机数的前 24 位将被忽略。那时,你为什么要选择 [0, 10000] 范围内的数字?