Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check that a method is not invoked

Tags:

java

jmockit

I want to check that a method is not run and tried to do it with an Expectation setting times = 0;, however I don't get the expected behaviour.

For example, the following test passes, although the Session#stop method is called, and the expectation has a times = 0; condition:

public static class Session {
    public void stop() {}
}

public static class Whatever {
    Session s = new Session();
    public synchronized void method() {
        s.stop();
    }
}

@Test
public void testWhatever () throws Exception {
    new Expectations(Session.class) {
        @Mocked Session s;
        { s.stop(); times = 0; } //Session#stop must not be called
    };
    final Whatever w = new Whatever();
    w.method(); // this method calls Session#stop => the test should fail...
                // ... but it passes
}

Note: If I replace the code with { s.stop(); times = 1; }, the test passes too: I must be missing something obvious here...

like image 860
assylias Avatar asked Oct 21 '12 21:10

assylias


People also ask

How do I know if a method has been called Mockito?

Mockito verify() simple example It's the same as calling with times(1) argument with verify method. verify(mockList, times(1)). size(); If we want to make sure a method is called but we don't care about the argument, then we can use ArgumentMatchers with verify method.

How do you verify in Mockk?

verify supports the same argument matchers as every , along with a few additional matchers. Inside the verification block (between the opening curly bracket { and closing curly bracket } ), you write the method you want to verify.

What is verifyNoMoreInteractions?

public static void verifyNoMoreInteractions(Object... mocks) Checks if any of given mocks has any unverified interaction. We can use this method after calling verify() methods. It is to make sure that no interaction is left for verification.


1 Answers

The reason of the unexpected mocking behavior is that you inadvertently used partial mocking on an strictly mocked type. In this case, recording an expectation with times = <n> means that the first n matching invocations will be mocked, and after that any additional invocations will execute the original "unmocked" method. With regular mocking instead, you would get the expected behavior (ie, an UnexpectedInvocation getting thrown after n invocations).

The proper way to write the test is:

public static class Session { public void stop() {} }
public static class Whatever {
    Session s = new Session();
    public synchronized void method() { s.stop(); }
}

@Test
public void testWhatever ()
{
    new Expectations() {
        @Mocked Session s;
        { s.stop(); times = 0; }
    };

    final Whatever w = new Whatever();
    w.method();
}

Alternatively, it can also be written with a verification block instead, which is usually better for situations like these:

@Test
public void testWhatever (@Mocked final Session s)
{
    final Whatever w = new Whatever();
    w.method();

    new Verifications() {{ s.stop(); times = 0; }};
}
like image 76
Rogério Avatar answered Oct 14 '22 15:10

Rogério