web-dev-qa-db-ja.com

@Spyと@Autowiredを一緒に使用する

3つのメソッドを持つサービスクラスがあります。サービスクラスもいくつかの@Autowiredアノテーションを使用しています。 3つの方法のうち、2つの方法を模擬したいのですが、3番目の方法には実際の方法を使用します。

問題は:

  1. @Spyで@Autowiredを使用している場合、3つすべての実際のメソッド実装が呼び出されています。
  2. @Spyのみを使用している場合、Autowiredオブジェクトの初期化がないため、実際のメソッドの呼び出しはNullポインターで返されます。
11
Shashi K Kalia

私はこれら2つのオプションについて知っています。

  1. 唯一の注釈として、spring-boot-testの @ SpyBean 注釈を使用します
@Autowired
@InjectMocks
private ProductController productController;

@SpyBean
private ProductService productServiceSpy;
  1. Javaリフレクションを使用して、スパイオブジェクトを「自動ワイヤリング」します。例 ReflectionTestUtils
@Autowired
private ProductController productController;

@Autowired
private ProductService productService;

@Before
public void setUp() {
    ProductService productServiceSpy = Mockito.spy(productService);
    ReflectionTestUtils.setField(productController, "productService", productServiceSpy);
}
20
PROrock

私は自分自身に驚いたが、それは私たちのために機能します。次のような場所がたくさんあります。

_@Spy
@Autowired
private FeatureService featureService;
_

あなたがこの問題に直面している理由を私は知っていると思います。それはインジェクションについてではなく、when(bloMock.doSomeStuff()).thenReturn(1)doReturn(1).when(bloMock).doSomeStuff()についてです。参照: http://www.stevenschwenke.de/spyingWithMockito

非常に重要な違いは、最初のオプションが実際にdoSomeStuff()-メソッドを呼び出すのに対して、2番目のオプションは呼び出さないことです。どちらも、doSomeStuff()が必要な1を返すようにします。

6
yuranos87

@Spy@Autowiredの併用は、そのスパイと、スパイが挿入された別のコンポーネントとの間の相互作用を確認するまで機能します。私にとってうまくいくとわかったのは https://dzone.com/articles/how-to-mock-spring-bean-version-2 にある次のアプローチです

@Configuration
public class AddressServiceTestConfiguration {
    @Bean
    @Primary
    public AddressService addressServiceSpy(AddressService addressService) {
        return Mockito.spy(addressService);
    }
}

これにより、自動配線されたコンポーネントがスパイオブジェクトに変わります。これは、サービスによって使用され、テストで検証できます。

0
Jakub Zawadzki