EasyMock test case failed saying method called incorrectly - unit-testing

Does anyone know what the numbers 5b40c281 and 78a1d1f4 mean in the EasyMock test case fail shown below?
Are they essentially address pointers to two different instances of PdlPrintJob?
Does anyone know why this fail is occurring?
In the main code, PdlPrintJob is constructed (using new PdlPrintJob()) and passed as a parameter to method printer.executePrintJob().
In the test case, PdlPrintJob is constructed (using new PdlPrintJob()) and passed as a parameter to mockPrinter.executePrintJob().
Thanks for any advice,
Best regards
James
junit.framework.AssertionFailedError:
Unexpected method call executePrintJob(com.canon.cel.meap.jobs.PdlPrintJob#5b40c281, EasyMock for interface com.canon.meap.security.AccessControlToken):
executePrintJob(com.canon.cel.meap.jobs.PdlPrintJob#5b40c281, EasyMock for interface com.canon.meap.security.AccessControlToken): expected: 0, actual: 1
executePrintJob(com.canon.cel.meap.jobs.PdlPrintJob#78a1d1f4, EasyMock for interface com.canon.meap.security.AccessControlToken): expected: 1, actual: 0

Its because you have done something like this in your test class.
EasyMock.expect(executePrintJob(new PdlPrintJob(),....))'
but actually it should have been a mockObject that you should have passed as parameter.
you need to do something like this
PdlPrintJob pdlPrintJob=Easymock.createNiceMock(PdlPrintJob.class);
Powermock.expectNew(PdlPrintJob).andReturn(pdlPrintJob).anyTimes(); //this will return the mocked instance of PDlPrintJob class wherever 'new' operator is used for this class
EasyMock.expect(executePrintJob(pdlPrintJob,.....)).andReturn(anythingYouWantToReturn).anyTimes(); // have added '.....' in case there are other parameters to this method
EasyMock.replay(pdlPrintJob);
Powermock.replayAll();
You were facing the issue because Easymock is a strict mocking framework, you had asked it to expect a particular method with particular object type only (its like tightly binding method expectation to a single object), and during execution as new operator was used the method expectation failed as object parameters didnt match the expectation of Easymock, resulting in this exception.
I always prefer doing something like this for method expectation
if my method to be tested is
public String compress(String str, Integer intr, double ch){}
I expect this method in easymock as follows:
EasyMock.expect(compress(EasyMock.anyObject(String.class),EasyMock.anyObject(Integer.class),EasyMock.anyDouble())).andReturn("Done compressing").anyTimes();
so by this approach my method expectation works for any valid parameters passed to my compress() method during test case execution.
Hope that helps!
Good luck!

Related

How to test (in google test) that a function is called with the correct parameters

I have a class and this class has a method ("original_method") that uses two objects of different types. In this method there are two calls: one call to a method of the first object that returns a value which is then used for calling a method of the second object. I was wondering what is the correct way of unit testing such behavior (using google-test). Specifically, I want to test that the argument provided to the second object is indeed the value returned from the first.
Currently I achieve this using parametrized tests - the code below shows what I do:
TEST_P(SomeTestSuite, checkingIfCalledWithTheRightArgument)
{
EXPECT_CALL(*obj1, get_some_value()).WillOnce(Return(name_of_value));
EXPECT_CALL(*obj2, do_a_calculation(name_of_value));
obj0->call_original_method();
}
I have a fixture for my original class under testing, i have mocks for obj1 and obj2, I provide a value for "name_of_value" in the parameters and the test works.
My problem is that this doesn't seem to be the correct way, I believe I shouldn't have to pass a parameter to check such a functionality. I would appreciate if somebody could explain to me how i should have approached the problem.
Thank you.
EDIT:
I think I could do:
TEST_F(SomeTestSuite, checkingIfCalledWithTheRightArgument)
{
EXPECT_CALL(*obj1, get_some_value());
auto name_of_value = obj1->get_some_value();
EXPECT_CALL(*obj2, do_a_calculation(name_of_value));
obj0->call_original_method();
}
but I'm not sure if this captures (or actually tests) the original behaviour...

googlemock EXPECT_CALL with small behaviour variations

With the help of googlemock and googletest, I set up a test that checks that different mocked errors are correctly handled by the method under test. Basically my code looks like this:
// setup mock object, and object under test
// setup initial EXPECT_CALL expectations
// this expected method call in the middle mocks a failure
EXPECT_CALL(*mock, method(arg_in)).
Times(1).
WillOnce(Throw(exception_of_type_A));
// setup cleanup EXPECT_CALL expectations
// Now invoke method in object under test.
// Expect exception has been translated to different type.
EXPECT_THROW(x.method_under_test(), exception_type_B);
// destructor of mock object will check the mock method invocations
Now my mocked method that fails here can not only fail by throwing an exception of type A, but also by throwing an exception of type B, or by returning an unexpected return value.
I can implement this easily enough by copying and pasting the complete TEST() and just changing what the misbehaving mocked method1 will do. But this will make the code messy. Even if I document that these 3 tests are exactly the same except for how the mocked method1 fails in the WillOnce() action specification, a human reader would still have to compare carefully if this is still true.
What would be the correct way in googletest/googlemock to share the common code between the three TESTS and just have them differ in the WillOnce() action?
To my mind comes: Macros, loops over a container with WillOnce() actions, googletest fixtures, static helper methods for setup and cleanup.
I am still new to googletest and not sure how to address this.
For now, I implement the test logic in a templated static function that accepts an action as a parameter:
template <typename A>
static void paramererizeable_test(A failingAction) {
// set everything up
EXPECT_CALL(*mock, method(arg_in)).
Times(1).
WillOnce(failingAction);
// set up more expectations
// trigger the calls
}
TEST(Section, Method) {
paramererizeable_test(Throw(exception_of_type_A));
paramererizeable_test(Throw(exception_of_type_B));
paramererizeable_test(Return(unexpected_return_value));
}
Not sure if this is how it should be done, or if there is a better way, but it works and is readable.

OCMock stub for method's pass-by-reference argument

I have a method that I need to stub. The method is of the form below:
BOOL myMethodWithError:(*__autoreleasing *NSError)error;
So I mocked the object and attempted to return a nil back through 'error'. I coded it as follows.
id mockMyObject = [OCMockObject mockForClass:[MyObject class]];
BOOL retVal = YES;
NSError *error = nil;
[[[mockMyObject stub] andReturn:OCMOCK_VALUE(retVal)] myMethodWithError:&error];
When the test is run and the mock object is operated, the error reference id appears to change. So the mock throws an exception:
OCMockObject[MyObject]: expected method invoked:
myMethodWithError:0xbfffca78
I have tried a number of different ways but each time the pointer value appears to change once the error object is passed to the method which causes the mock object to throw an error.
I simply need to test my business rules against the pass-by-reference value of the argument, but I can't seem to get the mock or test object to cooperate.
Thanks in advance, any help will be greatly appreciated.
Apart from the solutions Ben mentions in his answer(I only tested the one based on ignoringNonObjectArgs, and it works fine), I prefer to use [OCMArg anyPointer] with the appropriate cast:
[[[myMock stub] andReturn:something] someMethod:(NSError * __autoreleasing *)[OCMArg anyPointer]];
Use ignoringNonObjectArgs
[[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] ignoringNonObjectArgs] myMethodWithError:NULL];
From http://ocmock.org/features/
Arguments that are neither objects nor pointers or selectors cannot be
ignored using an any placeholder. It is possible, though, to tell the
mock to ignore all non-object arguments in an invocation:
[[[mock expect] ignoringNonObjectArgs] someMethodWithIntArgument:0]
In this
case the mock will accept any invocation of someMethodWithIntArgument:
no matter what argument is actually passed. If the method has object
arguments as well as non-object arguments, the object arguments can
still be constrained as usual using the methods on OCMArg.
Bonus Answer
This would also solve your issue:
[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] myMethodWithError:[OCMArg setTo:nil]];

EasyMock expected void

Just trying the EasyMock for the first time.
I seem to get it going but I am immediately halted with the fact that the mocked class runs a method "returning" void (EntityManager.remove(abc)).
I am able to mock the EntityManger partly to begin testing, i.e.
EasyMock.expect(this.mockManager.find(Some.class, id)).andReturn(mock);
, but how do I do the same for the 'remove' case?
I can't do (for example):
EasyMock.expect(this.mockManager.remove(rek)).andReturn(Boolean(true));
And if I do nothing, I get:
java.lang.AssertionError:
Unexpected method call EntityManager.remove(EasyMock for class my.package.Some)...
I need to test the logic before getting to remove part, but I don't care if it actually succeeds (would be a different thing).
You don't need to call EasyMock.expect(). Just use
this.mockManager.remove(rek);
while in the recording phase (before calling replay()).
If you want the mocked method, for example, to throw an exception or to be called twice, use expectLastCal():
this.mockManager.remove(rek);
expectLastCall().andThrow(new RuntimeException());
//or expectLastCall().times(2);

How do mock frameworks work?

If I was to write a mocking library, how would this work (in other words, how do "they work?)?
One of the things which I wonder is that you are always setting expectations so really you need to compare the expectation to what the method does at runtime, so I assume reflection (resolving types at runtime) is required.
Also, when using the term "mock object", is the object stubbed out or would it be an object with pre-set expectations?
When I think how I would write my own implementation of a framework/technique, like mock objects, I realise how much I really know (or don't know) and what I would trip up on: If the mock object is pre-programmed to return set expectations and you don't call the actual real object, then wouldn't the result always be the same? Eg:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs()
{
var fake = Isolate.Fake.Instance<ClassToIsolate>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, " abc")).WithExactArguments().WillReturn(10);
// MethodReturnInt will return 50 when called with arguments 3, "xyz"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "xyz")).WithExactArguments().WillReturn(50);
Assert.AreEqual(10, fake.MethodReturnInt(3, "abc"));
Assert.AreEqual(50, fake.MethodReturnInt(3, "xyz"));
}
Wouldn't this always return true?
The idea with mocking frameworks is to mock out dependencies, and not the actual classes under test. For your example, your test will always return true, because really you're only testing the mocking framework and not your actual code!
A real world mock would look more like this:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs() {
var fake = Isolate.Fake.Instance<DependencyClass>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "abc")).WithExactArguments().WillReturn(10);
var testClass = new TestClass(fake);
testClass.RunMethod();
// Verify that the setup methods were execute in RunMethod()
// Not familiar with TypeMock's actual method to do this...
IsolatorExtensions.VerifyInstanceWasCalled(fake);
// Or assert on values
Assert.AreEqual(10, testClass.AProperty);
}
Notice how the mock is passed into the TestClass and a method run on it.
You can read The Purpose of Mocking to get a better idea of how mocking works.
Update: Explanation why you're testing only the mocking framework:
What you've done is create a method MethodReturnInt with the mocking framework using Isolate.WhenCalled(). When you call MethodRecturnInt in the Assert, the code will run the delegate () => fake.MethodReturnInt() and return 10. The mocking framework is effectively creating a method (albeit dynamically) that would look something like this:
public void MethodReturnInt(int value, string value2) {
Assert.Equal(3, value);
Assert.Equal("abc", value2);
return 10;
}
It's a bit more complicated than that, but this is the general idea. Since you never run any code other than the creation of 2 methods and then asserts on those two methods, you're not testing your own code and therefore only testing the mocking framework.
Yes, it will always return true. Mock objects should be used when the class under test requires another class implementation that you don't want to involve in the test run. This is most useful when it's a class that uses interfaces with multiple implementations, or there are complex/expensive/external services that you don't want to set up.
In the above code, you're mocking the class that you're "testing".
Another way of thinking about it is that the mock behaviours you record are black-box (implementation) assertions, where Assert.* are white-box (api) assertions.
You have the right idea. You will often find that they have a couple of modes of operation. If you're worried about your method not getting called or it not getting called in the right order there is quite often a 'strict' mode that causes the mock framework to throw an exception if the method isn't called by the end of the test, or is called with the wrong parameters etc.
Most of the frameworks have thought of those sorts of issues so you just need to find out how to configure it for your scenario.
One way to look at how mock system work is just look at times when you need an object but you don't want to use the real class but instead want it to give you some specific kind of data that it wouldn't (or won't do so reliably). So if you see:
Assert.IsTrue(myLogic.IsNoon(time))
you can see how the assert would want the time object to always be noon. . . well you can't do that with a real object reliably. So you need a stand-in. You can make a fake class just for the test, but that's sort of heavy. Mock frameworks are a shortcut.