5

メソッドが実行されていないことを確認したいので、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
}

注: コードを に置き換えると{ s.stop(); times = 1; }、テストもパスします。ここに明らかな何かが欠けているに違いありません...

4

5 に答える 5

8

予期しないモック動作の理由は、厳密にモックされた型に対して誤って部分的なモックを使用したためです。この場合、 で期待値を記録するtimes = <n>ことは、最初にn一致する呼び出しがモックされ、その後の追加の呼び出しが元の「モックされていない」メソッドを実行することを意味します。代わりに通常のモックを使用すると、期待される動作 (つまり、呼び出しUnexpectedInvocation後にスローされる) が得られます。n

テストを記述する適切な方法は次のとおりです。

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();
}

または、代わりに検証ブロックを使用して記述することもできます。これは通常、次のような状況に適しています。

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

    new Verifications() {{ s.stop(); times = 0; }};
}
于 2012-10-23T10:58:46.707 に答える
3

これに関連して、JMockit、times = 0、および @Tested アノテーションに問題がありました。

@Tested アノテーションを使用すると、まだ「実際の」クラスがあるため、この実際のクラスに期待または検証を登録すると (時間 = 0 であっても)、JMockit はメソッドを実行しようとします。解決策は、Expectations でクラスを部分的にモックすることです。

@Tested
Session s;

new Expectations(Session.class) {{ 
   s.stop(); times = 0; } //Session#stop must not be called
};

これは、 @Tested クラスのメソッドで times=0 を使用することがわかった唯一の方法です。

于 2015-12-07T15:00:24.517 に答える
0

代わりに maxTimes を試してください。静的な方法で stop() を参照することもできます。

@Test
public void test(@Mocked Session mockSession){

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

  new Verifications(){
    {
       Session.stop();
       maxTimes = 0;
    }
  };
}
于 2016-07-26T12:46:12.247 に答える
0

クラスで回避策を見つけましたMockUp- 以下のテストは期待どおりに失敗します -元のアプローチが機能しなかった理由を理解したいと思います。

@Test
public void testWhatever () throws Exception {
    new MockUp<Session>() {
        @Mock
        public void stop() {
            fail("stop should not have been called");
        }
    };
    final Whatever w = new Whatever();
    w.method();
}
于 2012-10-21T22:24:33.083 に答える
-1

記憶から、のようなもの

verify( s  , times(0) ).stop();

動作します。問題は、SessioninWhateverがあなた@Mockのものではなく、別のオブジェクトであることです。

w.s = s;

直前にw.method()

乾杯、

于 2012-10-21T21:25:00.070 に答える