I'm telling mock object to wait for method with command:
mockObject.registerSQLDriver(isA(SomeName.class));
At runtime method is called exactly with instance of SomeName class, but the test fails telling that "Unexpected method call registerSQLDriver()"
What can cause this problem?
Here is the code:
resetToDefault(_SQLDriverManager);
_SQLDriverManager.registerSQLDriver(isA(SQLDriver.class));
expectLastCall().anyTimes();
replay(_SQLDriverManager);
Probably, you are mocking one instance and testing another instance.
To check this you should add a name parameter in the mock creation:
Comparable<String> mock01 = EasyMock.createMock("M1", Comparable.class);
Comparable<String> mock02 = EasyMock.createMock("M2", Comparable.class);
EasyMock.expect(mock01.compareTo(EasyMock.isA(String.class))).andReturn(1);
EasyMock.replay(mock01, mock02);
mock02.compareTo("Test");
EasyMock.verify(mock01, mock02);
In this case the test will fail with the message:
Unexpected method call M2.compareTo("Test")
instead of:
Unexpected method call Comparable.compareTo("Test")
Related
I'm trying to capture a parameter passed in input to a mock object with PowerMockito, this is the code:
//I create a mock object
ClassMocked mock = PowerMockito.mock(ClassMocked.class);
//Create the captor that will capture the String passed in input to the mock object
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
//When the method put is executed on my mock I want the second parameter (that is a String) to be captured
Mockito.verify(mock).put(anyString(), inputDataMapCaptor.capture());
//Creates the instance of the class that I want to test passing the mock as parameter
ClassToTest instance = new ClassToTest(mock);
//Executes the method that I want to test
instance.methodToTest();
/* I know that during the execution of "methodToTest()" mock.put(String,String) will be executed and I want to get the second string parameter. */
When I execute the test I have an exception executing the line Mockito.verify(mock).put(...);
"Wanted but not invoked mock.put(any,Capturing argument);"
What is wrong?
You should call instance.methodToTest(); before Mockito.verify(mock).put(anyString(), inputDataMapCaptor.capture());
verify() verifies that the specified method call did take place.
You can't verify "upfront" that a method call is supposed to happen.
Thus: verify() needs to happen after the facts, not before!
I have a class called
ServiceImpl
which implents the interface
Service
I have a method in another jar which I want to call but it takes
Service
as input. Here is the method:
public void setService(Service service) {
context.setService(service);
}
I tried to use reflection to call this method
final ServiceImpl myService = new ServiceImpl(param1, param2);
method = beanClass.getMethod("setService",Service.class);
method.invoke("setService", myService);
However I get the error:
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
It is saying that it expects a Service class but I am passing in an object of type ServiceImpl. But why should that be a problem, since ServiceImpl has implemented Service? How can I work around this?
You're trying to call setService on a string object, "setService". Method#invoke's first parameter is the object to call the method on, not the name of the method (it already knows who it is).
You wanted:
method.invoke(bean, myService);
...where bean is an instance of the class whose Class object beanClass refers to.
It is not the Service parameter that the reflection is complaining about, it is the first parameter. Effectively, your code attempts to do this:
"setService".setService(myService);
which does not work for obvious reasons.
Pass the object on which you want to set the service as the first parameter to fix this problem:
method.invoke(instanceOfBeanClass, myService);
I am having some trouble trying to unit test java code that at some point calls native methods. Basically, I am trying to use PowerMockito to mock the class that will eventually call native. I was able to mock non-void methods just fine, but I keep getting compilation errors when I try to mock a method of void return type. Here is an example of the code I'm trying to test:
public class ClassThatCallsNative {
void initObject(ByteBuffer param1, int param2) {
//calls native
}
int getId(int param1) {
//calls native
}
}
I have this code in my test class:
PowerMockito.when(mClassThatCallsNative.getId(Mockit.anyInt())).thenReturn(0);
This line of code compiles just fine, however the following line is where I get compilation error:
PowerMockito.when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt())).doNothing();
The error message just says invalid void parameter and points to .initObject.
Any idea what I am doing wrong?
Since you are trying to mock method which returns void, you simply can't call it inside when() method. This is because PowerMockito.when() methods expects T methodCall but got void, this is the reason for compilation failure.
Instead you should use this syntax:
PowerMockito.doNothing().when(mClassThatCallsNative).initObject(any(ByteBuffer.class), anyInt())
any() and anyInt() methods are part of Mockito class.
For void methods, you need to use below one
PowerMockito.doNothing().when(mClassThatCallsNative.initObject(Mockit.any(ByteBuffer.class), anyInt()))
Figured out what the problem was, at last. Turns out I needed the instance of ClassThatCallsNative in order to mock it's methods. What was happening before is that the object was being initialized inside a constructor call, but when I created another constructor that takes ClassThatCallsNative as a parameter, and set my instance to that instead, everything worked fine.
Thank you anyways!
I have a method which I am trying to call dynamically. That method has an argument 'stringValue'. The method I am trying to invoke is in the parent (receivers??) class.
I can't figure out how to get the reference back to the parent
java.lang.reflect.Method method;
method = Class.forName("com.blah.MyActivity").getMethod("myFunction", String.class);
method.invoke(this,stringValue);
Gives the error:
'Message expected receiver of type com.blah.MyActivity, but got com.blah.MyActivity$SubTask'
I suspect you want:
method.invoke(MyActivity.this, stringValue);
The MyActivity.this part is the way of getting to the enclosing instance of MyActivity.
See section 15.8.4 of the JLS for more details.
I'm using EasyMock to create mock that is one of private parameters (without setter) in tested class. I tried using reflection - but it does not work correctly.
public class TestedClassTest{
#Test
public void test(){
TestedClass instance = new TestedClass();
MockedClass mocked = EasyMock.createMock(MockedClass.class);
Data data = new Data();
//Void setter
DataType dataType = (myDataType.DataType) EasyMock.anyObject();
mocked.setDataType(dataType);
EasyMock.expectLastCall();
//expect
EasyMock.expect(mocked.getData()).andReturn(data);
EasyMock.replay(mocked);
Field field = instance.getClass().getDeclaredField("mockedClass")
field.setAccessible(true);
field.set(instance, mocked);
//run tested method
instance.someAction();
EasyMock.verify(mocked);
}
}
Im getting FAILED info:
Unexpected method call MockedClass.setDataType(myData.MyData#104306d75):
MockedClass.getData(): expected: 1, actual: 0
junit.framework.AssertionFailedError:
Unexpected method call MockedClass.setDataType(myData.MyData#132006d75):
MockedClass.getData(): expected: 1, actual: 0
Im sure this method is fired on "MockedClass" object during tested "instance.someAction()"
How to resolve this problem?
Edited - Answer :
After correcting doubled replay.mocked() I found (so simple!) that one more void method should be declared using EasyMock.expectLastCall()
Your reflection code looks fine.
It's been a long time since I've used EasyMock, but isn't replay only supposed to be called once per mock in a test? You are calling it twice. Try getting rid of the first replay call.
In this case, does it make sense to have the field that contains the mock be public? In general, collaborators should be set via either constructor or setter, eliminating the need for reflection at all.
EDIT -- based on your updates -- the error indicates setDataType was called on the mock, but the mock did not expect it to be called. Perhaps your class is calling it twice, perhaps it is being called out of order, or calling it with an argument you didn't expect (although I would expect the error to be different in this case).