web-dev-qa-db-ja.com

EasyMock 3.0、モッキングクラスはJava.lang.IllegalStateExceptionをスローします:モックの最後の呼び出しは利用できません

次の単体テストを実行すると、例外がスローされます。Java.lang.IllegalStateException:モックの最後の呼び出しはありません


import org.easymock.*;
import org.junit.*;

public class MyTest {

    @Test
    public void testWithClass() {
        Thread threadMock = EasyMock.createMock(Thread.class);
        EasyMock.expect(threadMock.isAlive()).andReturn(true);
    }
}

私は何が間違っているのかわかりませんし、ウェブ上で良い例を見つけることができません。 EasyMock 3.0を使用してクラスをモックする方法を教えてください。上記の単体テストの何が問題になっていますか?どんな助けでも大歓迎です。

私のプロジェクトには次のMaven依存関係が含まれています

<dependency>
   <groupId>org.easymock</groupId>
   <artifactId>easymock</artifactId>
   <version>3.0</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib-nodep</artifactId>
   <version>2.2</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.objenesis</groupId>
   <artifactId>objenesis</artifactId>
   <version>1.2</version>
   <scope>test</scope>
</dependency>
22
Nathan Reese

この例外の理由は、Thread#isAlive()finalメソッドであることですが、EasyMockはfinalメソッドのモックをサポートしていません。そのため、EasyMock.expect(...)内にあるこのメソッドの呼び出しは、「モックの呼び出し」とは見なされません。

Finalメソッドをモックするには、JMockit(私が開発したもの)などの別のモッキングツールが必要になります。

public void testMockingFinalMethod(@Mocked("isAlive") Thread mock)
{
    new Expectations()
    {{
        mock.isAlive(); result = true;
    }};

    assertTrue(mock.isAlive());
}

モックAPIでは、一般的に、モックされるメソッドを明示的に指定する必要はありません。ただし、Threadクラスは扱いにくいクラスです。

19
Rogério

prepared作成したモックオブジェクトがない場合を除いて、テストメソッドは正常に見えます。これは、

_EasyMock.replay(mockObject1, mockObject2, ...);
_

これにより、モックされたオブジェクトが準備され、JUnitの実行時に使用されるようになります。依存関係にも問題はありません。

また、あなたはここでユニットテストしている実際のメソッドを呼び出していないようです。通常、テストメソッドを作成する方法は、JUnitメソッドを作成し、モックライブラリ(EasyMockやPowerMockなど)を使用して、テストメソッドコンテキストを超えた外部オブジェクトがある場合にのみ使用し、モックされたすべてのオブジェクトを再生します(これにより、テストで実際のビジネスオブジェクトの代わりとなるモック)。その後、テストしようとしている実際のメソッドを呼び出し、org.junit.Assert.assertXXX()メソッドを使用して機能を検証します。

11
Nagendra U M

1つのテストケースまたはスイート内でEasyMock.replay(mock)を複数回呼び出してこの問題を引き起こし、それぞれの間でEasyMock.reset(mock)を呼び出すと問題が解決しました。

0
SlappyTheFish