3

EasyMock を使用して、Java で JUnit テスト用のモック オブジェクトを作成しています。モック オブジェクトを作成し、メソッドが呼び出されることを期待する別のスレッドに渡します。他のスレッドでは、呼び出しはブロックに囲まれているtry/catch(Throwable)ため、モックで予期しない呼び出しが発生して がスローさAssertionErrorれた場合、そのエラーは catch ブロックによってキャッチされ、処理されます。したがって、予期しない呼び出しが発生しても、テストはパスします。

EasyMock.verify(mock)テストが期待どおりに失敗するようにするために、最後にテストランナースレッドで行われた呼び出しへの呼び出しのすべての検証を遅らせたいと思います。これは可能ですか?

4

4 に答える 4

1

EasyMockでこれを行う方法はわかりませんが、テストの最後に検証アサーションを指定できるため、 Mockitoでこの動作が可能です。

于 2010-01-05T13:13:43.747 に答える
1

私が推測する正しい解決策は、キャッチをやめることですThrowable。そうするErrorことで、見つけたすべての s がキャッチされますが、これは非常に危険な場合がありますThrowable。なんで?

(そうであることが判明した場合は、AssertionError具体的にキャッチして再スローできます。しかし、それは醜いです!)

于 2010-01-05T09:15:27.713 に答える
0

@deterb が示唆したように、Mockito では可能ですが、メソッド名を知っているか、すべてのメソッドに期待値を設定する必要があります。次に例を示します。

モックされたインターフェース:

public interface MyInterface {

    void allowedMethod();

    void disallowedMethod();
}

キャッチするユーザークラスAssertionError:

public class UserClass {

    public UserClass() {
    }

    public static void throwableCatcher(final MyInterface myInterface) {
        try {
            myInterface.allowedMethod();
            myInterface.disallowedMethod();
        } catch (final Throwable t) {
            System.out.println("Catched throwable: " + t.getMessage());
        }
    }
}

そしてMockitoテスト:

@Test
public void testMockito() throws Exception {
    final MyInterface myInterface = mock(MyInterface.class);

    UserClass.throwableCatcher(myInterface);

    verify(myInterface, never()).disallowedMethod(); // fails here
}

EasyMock でも同じことが可能ですが、いくつかの作業が必要です。

@Test
public void testEasyMock() throws Exception {
    final AtomicBoolean called = new AtomicBoolean();
    final MyInterface myInterface = createMock(MyInterface.class);
    myInterface.allowedMethod();

    myInterface.disallowedMethod();
    final IAnswer<? extends Object> answer = new IAnswer<Object>() {

        @Override
        public Object answer() throws Throwable {
            System.out.println("answer");
            called.set(true);
            throw new AssertionError("should not call");
        }

    };
    expectLastCall().andAnswer(answer).anyTimes();

    replay(myInterface);

    UserClass.throwableCatcher(myInterface);

    verify(myInterface);
    assertFalse("called", called.get()); // fails here
}

myInterface.disallowedMethod()残念ながら、ここではメソッド名も知っている必要があり、や などの期待値を定義する必要がありますexpectLastCall().andAnswer(answer).anyTimes()

もう 1 つの可能性は、Proxyクラスを使用して( customInvocationHandlerを使用して) プロキシを作成し、それをモック オブジェクトとして使用することです。確かにもっと作業が必要ですが、最もカスタマイズ可能なソリューションになる可能性があります。

最後に、EasyMock モック オブジェクトへの委任の有無にかかわらず、カスタム実装を作成することも可能であることを忘れないでください。ここに委任のあるものがあります:

public class MockedMyInterface implements MyInterface {

    private final MyInterface delegate;

    private final AtomicBoolean called = new AtomicBoolean();

    public MockedMyInterface(final MyInterface delegate) {
        this.delegate = delegate;
    }

    @Override
    public void allowedMethod() {
        delegate.allowedMethod();
    }

    @Override
    public void disallowedMethod() {
        called.set(true);
        throw new AssertionError("should not call");
    }

    public boolean isCalled() {
        return called.get();
    }

}

そしてそれのためのテスト:

@Test
public void testEasyMockWithCustomClass() throws Exception {
    final MyInterface myInterface = createMock(MyInterface.class);
    myInterface.allowedMethod();

    final MockedMyInterface mockedMyInterface = 
        new MockedMyInterface(myInterface);

    replay(myInterface);

    UserClass.throwableCatcher(mockedMyInterface);

    verify(myInterface);
    assertFalse("called", mockedMyInterface.isCalled()); // fails here
}
于 2012-06-29T20:01:34.550 に答える
0

素敵なモックを使ってみてください:

http://easymock.org/EasyMock2_5_2_Documentation.html

「ナイス モック createMock() によって返されるモック オブジェクトでは、すべてのメソッドのデフォルトの動作は、すべての予期しないメソッド呼び出しに対して AssertionError をスローすることです。デフォルトですべてのメソッド呼び出しを許可し、適切な空を返す「ナイス」モック オブジェクトが必要な場合値 (0、null、または false) を使用する場合は、代わりに createNiceMock() を使用してください。"

AssertionError をスローする代わりに、予期しない呼び出しに対してデフォルト値が返されますが、verify() メソッドを使用してそれらを検証することはできます (この場合、AssertionErrors がスローされます)。

于 2010-01-05T14:37:46.050 に答える