Error using Mock: Wanted but not invoked: Actually, there were zero interactions with this mock

4

I am making a list of exercises and I am in doubt about the following:

  

Exercise 3 - The verify method, from the org.mockito.Mockito.verify package, is   used to check the amount of times a method is invoked.   Add in the ATest class a test to check if invoking method   area (2) the pi () method is invoked exactly once.

The class to be tested is as follows:

package aula;

public abstract class A {
    public long fatorial(long n) {
        if (n <= 1) {
            return 1;
        }
        return n * fatorial(n - 1);
    }

    public abstract Object calc(Object x, Object y) throws 
    NullPointerException, Exception;

    public void msg(String txt) {
    }

    public double area(double r) {
        return 2 * pi() * r;

    }

    public double pi() {
        return Math.PI;
    }

    public double pow() {
        return pi() * pi();
    }

    public abstract int inc();
} 

The test I created using JUnit 4 to solve exercise three is as follows:

@Test
public void test7() throws Exception {
    when(a.area(2)).thenReturn(2.0);
    //when(a.area(2.0)).thenCallRealMethod();
    verify(a, times(0)).pi();
    //assertSame(2.0, a.area(2));
    verify(a, times(1)).pi();
}

As we can see, I'm very confused with this question, I researched many things and could not heal my doubt. When I try to run this test, the result is blue not green as expected. The following error appears:

  

Wanted but not invoked: Actually, there were zero interactions with   this mock.

If someone can help me, explaining with the class that I put up there, I thank you! I really can not do it):

    
asked by anonymous 01.04.2018 / 05:23

1 answer

4

You are checking if the pi() method is called once, but you do not call it at any time. That's exactly what the error is saying:

  

Wanted but not invoked: Actually, there were zero interactions with   this mock.

     

Required, but not invoked, there were no interactions with this mock.

The first problem is that you sometimes say that the method needs to be called zero times:

verify(a, times(0)).pi();

And now you say that the method needs to be called once:

verify(a, times(1)).pi();

This is not the root of the problem, but will cause a problem later. In this case, only the second verify is required.

This line of code: when(a.area(2)).thenReturn(2.0); is not calling the method. You are only defining what the mock behavior should be when you call the area method by passing the value 2 as an argument. That is, when you make this call: area(2) , regardless of the implementation of the area method, the value 2.0 will be returned. If you pass any value other than 2, mock will not do anything because you have not defined what the behavior should be for other values.

In your case, in order for your verify to work, you need to call the actual method because the pi() method is called in the actual method. If you use this when(a.area(2)).thenReturn(2.0); code snippet, when the area(2) method is called, the pi() method will never be called. The value 2.0 will be returned immediately.

Your method should be implemented this way:

@Test
public void test7() throws Exception {
    // Define o comportamento do mock. 
    //Nesse caso o mock deverá chamar o método real caso o valor dois seja passado como argumento. 
    when(a.area(2)).thenCallRealMethod(); 
    //chama o método a ser testado
    a.area(2);
    //Verifica se o método pi() foi chamado uma vez.
    verify(a, times(1)).pi();
}

If you want the verify to work for any value passed as an argument, you can implement the method in this way:

@Test
public void test7() throws Exception {
    // Define o comportamento do mock. 
    //Nesse caso o mock deverá chamar o método real se qualquer valor Double for passado como argumento 
    when(a.area(any(Double.class))).thenCallRealMethod(); 
    //chama o método a ser testado
    a.area(5);
    //Verifica se o método pi() foi chamado uma vez.
    verify(a, times(1)).pi();
}
    
02.04.2018 / 18:25