0

I am testing a method in class which in turn calls another artifacts' method and consume return value in it.

public void methodToTest()
{
      Object reply = artifactObj.anotherMethod(object);
      if(reply == null)
            return;
      Object =reply.getData();
}

I have used powermockito and know that if "anotherMethod" existed inside the same class I could have easily spied it over. But I am not sure how can I do same when method is not in same class.

My attempt-:

Object mockObject = mock(Object.class);
Object mockReply = mock(Object.class);
Mockito.when(artifactObj.anotherMethod(mockObject)).thenReturn(mockReply);

//Now call original test method 

Class c = new Class(artifactObj);
c.methodToTest(); 

doing above will always return reply = null inside original method that I am trying to test. I need some value of reply to be returned so that I can use it inside my method.

Mr. Wonderful
  • 189
  • 4
  • 13
  • 1
    Where does `Class.artifactObj` get set? The best solution is to replace that with a _mock_, created using _normal Mockito and not Powermock_, and then you can pass it in. (Possible dupe: [How to use Mockito when we cannot pass a mock object to an instance of a class](http://stackoverflow.com/a/27552765/1426891)) – Jeff Bowman May 19 '15 at 20:07
  • that's been set inside the constructor. I pass mock instance of artifactObj in the constructor. I do this.-: ArtifactClass spy = PowerMockito.Spy(new ArtifactClass()); Powermocktio.doReturn(object).when(spy, "anotherMethod", object); Then pass spy inside the constructor call – Mr. Wonderful May 19 '15 at 21:35
  • Now instead of calling mock that I defined it calls original "anotherMethod" implementation. – Mr. Wonderful May 19 '15 at 21:38

1 Answers1

3

Null is returned because mocked method is never called:

In your example when mocking you are passing a mockObject as a matcher, as a result mocked response is only returned when said method is invoked using the same mockObject as a parameter. What you should do is introduce a matcher instead of it.

In example below Matchers.any(OriginalArgumentClass.class) is used, what it does is match any call to the method using any object as a parameter and return mocked reply.

Object reply = new Object();
ArtifactClass artifactObjMock = Mockito.mock(ArtifactClass.class);
Mockito.when(artifactObjMock.anotherMethod(Matchers.any(OriginalArgumentClass.class))).thenReturn(reply);

Now pass artifactObjMock to a constructor call:

Class c = new Class(artifactObjMock);
c.methodToTest(); 

This works under assumption that in your constructor you are assigning the passed value to the artifactObj field.

Mindaugas
  • 885
  • 9
  • 12
  • good catch there. But I am passing it in my real problem. I think I missed it my question. Editing it. – Mr. Wonderful May 20 '15 at 14:04
  • @Mr. Wonderful Had a fresh look at the problem, and figured it would be a good idea to edit my answer in order to point out why your approach is not working. – Mindaugas May 21 '15 at 05:48
  • that was it.. for some reason Matcher.anyObject() was giving casting error so I ended up using Matcher.any(OriginalArgumentClass.class). – Mr. Wonderful May 21 '15 at 14:11