检查是否未调用方法

ass*_*ias 5 java jmockit

我想检查一个方法没有运行并尝试使用Expectation设置times = 0;,但是我没有得到预期的行为.

例如,以下测试通过,虽然Session#stop调用了该方法,并且期望具有以下times = 0;条件:

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
}
Run Code Online (Sandbox Code Playgroud)

注意:如果我用代码替换代码{ s.stop(); times = 1; },测试也会通过:我必须遗漏一些明显的东西......

Rog*_*rio 8

出现意外模拟行为的原因是您无意中对严格模拟的类型使用了部分模拟.在这种情况下,记录期望times = <n>意味着n将模拟第一个匹配的调用,之后任何其他调用将执行原始的"unmocked"方法.使用常规模拟,您将获得预期的行为(即,UnexpectedInvocationn调用后抛出).

编写测试的正确方法是:

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();
}
Run Code Online (Sandbox Code Playgroud)

或者,它也可以用验证块编写,这通常适用于以下情况:

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

    new Verifications() {{ s.stop(); times = 0; }};
}
Run Code Online (Sandbox Code Playgroud)