3

CDI を使用したプロジェクトがあり、モックを使用して単体テストを作成したいと考えています。モックを管理するには EasyMock を使用し、CDI で実行するには、使いやすいと思われる cdi-unit プロジェクトを見つけました。

CDI コンテキストで EasyMock を使用してモックを取得するのに問題があります。これが私の単体テストです:

@RunWith(CdiRunner.class)
@AdditionalClasses(MockFactory.class)
public class ResultYearMServiceImplTest {

    @Inject
    private IStockDao stockDao;

    @Inject
    private ResultYearMServiceImpl resultYearMService;

    @Test
    public void getResultList() {
        EasyMock.reset(stockDao);
        EasyMock.expect(stockDao.getListStocks()).andReturn(null).once()
                .andReturn(new ArrayList<DtoStock>()).once();
        EasyMock.replay(stockDao);
    }
}

IStockDao はテストでモックにする必要があるため、それを取得するには、次のような @Produces メソッドを使用したいと思います (@AdditionalClasses によって cdi ユニットに与えられた MockFactory クラスで):

@Produces
@ApplicationScoped
public IStockDao getStockDao() {
    return EasyMock.createMock(IStockDao.class);
}

単体テストを実行すると、モックは単体テストに適していますが、次のエラーが発生します。

java.lang.IllegalArgumentException: モックではありません: org.jboss.weld.proxies.IStockDao$-1971870620$Proxy$_$$_WeldClientProxy

これは、CDI が EasyMock IStockDao のインスタンスを提供するのではなく、プロキシ化されたインスタンスを提供し、EasyMock がこれらのメソッド (reset メソッドなど) でこれを受け入れないために発生します。

したがって、MockFactory の @ApplicationScoped をインスタンスをプロキシしない @Dependent に置き換えますが、新しい問題があります。

この注釈は、各インジェクション ポイントでモックの新しいインスタンスを提供するので、単体テストにモックを使用して、テスト対象のクラスで呼び出されるメソッドをモックするため、それを使用できます。そして、モックのこのインスタンスは、テストされたクラスで同じでなければなりません (@Dependent の場合はそうではありません)。

単体テストとテスト済みクラスで同じインスタンスを取得するにはどうすればよいですか?

ありがとう。

4

3 に答える 3

3

Needle は、CDI をテストするための友達です。

http://needle.spree.de

public class ResultYearMServiceImplTest {
   @Rule
   public final NeedleRule needle = new NeedleRule();

   @Inject
   private IStockDao stockDao;

   @ObjectUnderTest
   private ResultYearMServiceImpl resultYearMService;
@Test
public void getResultList() {
    EasyMock.reset(stockDao);
    EasyMock.expect(stockDao.getListStocks()).andReturn(null).once()
            .andReturn(new ArrayList<DtoStock>()).once();
    EasyMock.replay(stockDao);
}
}
于 2013-05-26T21:12:25.797 に答える
1

CDI-Unit の次のバージョン (2.1.1) では、Mockito が現在サポートされているのと同じ方法で EasyMock のサポートが追加されます。

于 2013-08-12T20:56:46.073 に答える
1

easymock を使用して CDI インターセプターの単体テストを行っていましたが、あなたと同じ問題がありました。

私が使った回避策を共有したいと思います。@Dependent スコープでモックを生成することにあります。このようにして、easymock で CDI プロキシの問題を解決できます。

import static org.easymock.EasyMock.createStrictControl;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;


/**
 * Mock producer. Beans are produced in Dependent scope to not be proxied.
 */
@ApplicationScoped
public class CdiMockProducerUnitTests {

    /**
     * Mock
     */
    private final MyMockClass myMock;

    /**
     * Constructor creating mocks.
     */
    public CdiMockProducerTestesUnitarios() {
        myMock =  createStrictControl().createMock(MyMockClass.class);
    }

    /**
     * Produces mock in dependent scope.
     *
     * @return mock
     */
    @Produces
    @Dependent
    public MyMockClass produceMock() {
        return myMock;
    }

}
于 2013-05-29T12:44:23.203 に答える