2

I want to mock a concrete class in a TestNG test case. The class could look like this (simplified example):

public class Example() {

  private MyHello myHello;

  public Example(MyHello myHello) {
    this.myHello = myHello;
  }

  public String doSomething() {
    return myHello.doSomethingElse();
  }
}

Now we want to mock Example return some defined value:

@BeforeMethod
public void setUp() {
  this.example = mock(Example.class);
  when(this.example.doSomething()).thenReturn("dummyValue");
}

This looks quite good but in fact it isn't. The last line in the setup method calls the method on an instance of Example, this instance didn't get an MyHello through the constructor and so I get a NPE in the setUp method.

Is there a way to either inject an MyHello while creating the mock or to disallow Mockito calling the method on a real instance?

Edit

The issue, that caused the observed behaviour was, that the doSomething() method is actually final. I overlooked that when I tried to solve that issue. And this is a known limitation with mockito anyway. So I'll either remove the finals or extract an interface for that class.

Community
  • 1
  • 1
Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • Did you actually run your example? Does it produce the NPE? It shouldn't, unless Mockito interacts with CDI/Guice in a weird way. – Urs Reupke Nov 20 '12 at 11:55
  • Yes, I actually run into the NPE. It should work this way? I think I'll clean up my whole environment (again) and try again. – Andreas Dolk Nov 20 '12 at 12:06
  • Problem solved (facepalm). The method `doSomething()` is `final`. I overlooked that. And this is a well known limitation (http://stackoverflow.com/a/3794448/105224) – Andreas Dolk Nov 20 '12 at 13:11
  • Let me correct this a limitation of the JVM itself, as we are not rewriting bytecode, which is the way Powermock works (it reloads modified classes in new classloader by the way) – bric3 Nov 20 '12 at 13:20

2 Answers2

2

See if using doReturn("dummy").when(example).doSomething() does the trick.

Mockito.doReturn

From JavaDoc:

Use doReturn() in those rare occasions when you cannot use when(Object). Beware that when(Object) is always recommended for stubbing because it is argument type-safe and more readable (especially when stubbing consecutive calls).

Here are those rare occasions when doReturn() comes handy:

  1. When spying real objects and calling real methods on a spy brings side effects

    List list = new LinkedList();

    List spy = spy(list);

    //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo");

    //You have to use doReturn() for stubbing: doReturn("foo").when(spy).get(0);

John B
  • 32,493
  • 6
  • 77
  • 98
0

You can benefit from spy keyword instead of mock.

As far as I'm concerned from the documentation of Mockito, you are able to make partial mock with spy.

For detailed explanation you can benefit from subject 13 in the doc of it.

ibrahimyilmaz
  • 18,331
  • 13
  • 61
  • 80
  • Not exactly - in my case, calling the real method is not wanted. And that's what a spy would do. I want to train a mock so that it returns a dummy value if the method is called with some expected values. – Andreas Dolk Nov 20 '12 at 14:41