5

クラスがあり、サービスにプロキシを挿入しています。

Service service
{
    private ServiceProxy proxy;
    public Service(ServiceProxy proxy)
    {
        this.proxy = proxy; 
    }
}

そのためのテストは次のとおりです。

ServiceTest
{
    @Mock
    ServiceProxy mockProxy;
    Service service = new Service(mockProxy);
}

このようにクラスを初期化NPEすると、サービス オブジェクトを使用したいときに常に取得されます。なぜMockitoこれを行うのですか?すべてのテストで宣言する代わりに、これを回避する簡単な方法は何ですか?

4

2 に答える 2

9

Mockito バージョン 1.9.0 以降を使用している場合、目的を達成するための最良の方法は次のとおりです。

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private ServiceProxy proxy;

    @InjectMocks
    private Service service;

    @Test
    public void test() {
        assertNotNull(service);
        assertNotNull(proxy);
    }
}

最初のことは、@RunWith(MockitoJUnitRunner.class)明示的な初期化なしで @Mock および @InjectMocks アノテーションを自動的に機能させる宣言です。2 つ目は、Mockito 1.9.0 以降の @InjectMocks アノテーションで、サービスクラスに最適なコンストラクター インジェクションメカニズムを使用できるようになったことです。

@InjectMocks のその他のオプションは、セッター インジェクションフィールド インジェクション( docs BTW を参照) ですが、それらを使用するには引数なしのコンストラクターが必要です。

要約すると、次の理由でコードが機能しません。

  • MockitoJUnitRunner も MockitoAnnotations.initMocks(this) も使用していないため、@Mock アノテーションは効果がありません
  • 上記が満たされていても、テストが構築された後にmockProxyが初期化され、テストクラスの構築中にサービスが初期化されようとするため、例は失敗します。したがって、nullのmockProxy参照を受け取ります。

何らかの理由で @InjectMocks を使用したくない場合、唯一の方法は、テスト メソッド本体内または @Before アノテーション付き setUp メソッド内でServiceオブジェクトを構築することです。

于 2013-10-26T18:17:29.000 に答える
3

Serviceのモックで初期化されるテストクラスを次のように記述しServiceProxyます。

class ServiceTest
{
@Mock
ServiceProxy mockProxy;

//This will inject the "ServiceProxy" mock into your "Service" instance.
@InjectMocks
Service service = new Service(mockProxy);

@Before
public void init() {
//This will initialize the annotated mocks 
MockitoAnnotations.initMocks(this);
}

@Test
public void test() {
... 
}
}
于 2013-10-25T02:46:00.713 に答える