Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject EasyMock mock into tested class private field

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()

like image 543
Marcin Avatar asked Oct 09 '22 05:10

Marcin


1 Answers

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).

like image 110
hvgotcodes Avatar answered Oct 12 '22 21:10

hvgotcodes