Thoppan / powermock

Automatically exported from code.google.com/p/powermock
Apache License 2.0
0 stars 0 forks source link

Powermock replaying expectations too early #271

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What version of the product are you using? On what operating system?
1.4

Please provide any additional information below.

Snippet:

10. Inventory inv1 = new Inventory();
11. inv1.setQuantity(10);
12. expectNew(Inventory.class).andReturn(inv1);

// after some more un-related expectations

36. Inventory inv2 = new Inventory();
37. inv2.setQuantity(20);
38. expectNew(Inventory.class).andReturn(inv2);

// some more un-related expectations

51. PowerMock.replayAll();

When executing this test case, I am getting the following error at line 36:

java.lang.IllegalStateException: Must replay class Inventory to get configured 
expectation.
    at org.powermock.api.easymock.internal.invocationcontrol.NewInvocationControlImpl.invoke(NewInvocationControlImpl.java:60)
    at org.powermock.core.MockGateway.newInstanceCall(MockGateway.java:188)
    at com.demo.ShoppingCartManagerTest.testAddToCart1WithProductAndbooleanAndShoppingCartForTestcase1(ShoppingCartManagerTest.java:36)

I have a constraint and I cannot put the creation of inv2 before the first 
expectNew on line 12. Is the replay happening too early? Shouldn't Powermock 
wait till it encounters replayAll() before it starts using up expectations? or 
have I understood it wrong?

I am on an extremely tight schedule. Please help. Thanks

Original issue reported on code.google.com by vivek.ka...@gmail.com on 4 Aug 2010 at 1:51

GoogleCodeExporter commented 9 years ago
You need to prepare the class that instantiates Inventory (i.e. does new) for 
test.

Original comment by johan.ha...@gmail.com on 5 Aug 2010 at 9:10

GoogleCodeExporter commented 9 years ago
Hi Johan, The creation of Inventory object happens in my Test class as well as 
my source class. 

I am preparing my class under test. I also tried with preparing my test class 
as well. But the error remains. 

We could solve the problem by keeping a flag which was set in the replay() 
methods. Until the flag was set, any new invocations were ignored. When 
replay() is called, the flag is set and the present behavior continues.

If this kind of flag was provided as a setting, it would really help us. Please 
let us know what you would recommend.

Thanks

Original comment by vivek.ka...@gmail.com on 5 Aug 2010 at 9:56

GoogleCodeExporter commented 9 years ago
It would really help if you could provide a small example (code under test as 
well as a test case) that demonstrates the issue and I'll look into it.

Original comment by johan.ha...@gmail.com on 8 Aug 2010 at 6:05

GoogleCodeExporter commented 9 years ago
Johan, Please find sample source code attached...Running the given testcase 
will recreate the problem.

Thanks for your help!

Original comment by vivek.ka...@gmail.com on 9 Aug 2010 at 2:15

Attachments:

GoogleCodeExporter commented 9 years ago
I've had a look at it now. The reason is that you do "new" after you've 
expected a new of instance of the same type. E.g. 

A a1 = new A();
expectNew(A.class).andReturn(a1);

A a2 = new A(); // Here a2 will be substituted for a1
expectNew(A.class).andReturn(a2); // Here powermock will scew up.

A work-around would be to declare your instances before any expectNew call:
A a1 = new A();
A a2 = new A();
expectNew(A.class).andReturn(a1);
expectNew(A.class).andReturn(a2);

(or more shortly: "expectNew(A.class).andReturn(a1).andReturn(a2);")

I'm not sure how to fix this in a good way or if it even should be fixed at all 
(perhaps a better error message at least).

I'm attaching a refactored version of the test that uses the workaround I've 
mentioned. I've also added a new version of the test which I think is a better 
way to test the method (which doesn't use expectNew) that you may consider. 

Original comment by johan.ha...@gmail.com on 13 Aug 2010 at 1:17

Attachments: