Mockitoの@Mock
および@InjectMocks
アノテーションを使用して、Springの@Autowired
アノテーションが付けられたプライベートフィールドに依存関係を注入しています。
@RunWith(MockitoJUnitRunner.class)
public class DemoTest {
@Mock
private SomeService service;
@InjectMocks
private Demo demo;
/* ... */
}
そして
public class Demo {
@Autowired
private SomeService service;
/* ... */
}
今、私はrealオブジェクトをプライベートな@Autowired
フィールド(セッターなし)に注入したいと思います。これは可能ですか、またはメカニズムはモックの注入のみに制限されていますか?
@Spy
アノテーションを使用する
@RunWith(MockitoJUnitRunner.class)
public class DemoTest {
@Spy
private SomeService service = new RealServiceImpl();
@InjectMocks
private Demo demo;
/* ... */
}
Mockitoは、@Mock
または@Spy
注釈を持つすべてのフィールドを、@InjectMocks
注釈が付けられたインスタンスに注入される潜在的な候補と見なします。上記の場合、'RealServiceImpl'
インスタンスは「デモ」に挿入されます
詳細については
Add to @Dev Blanked answerでは、Springによって作成された既存のBeanを使用する場合、コードを次のように変更できます。
@RunWith(MockitoJUnitRunner.class)
public class DemoTest {
@Inject
private ApplicationContext ctx;
@Spy
private SomeService service;
@InjectMocks
private Demo demo;
@Before
public void setUp(){
service = ctx.getBean(SomeService.class);
}
/* ... */
}
この方法では、テストを機能させるためだけにコードを変更する(別のコンストラクターを追加する)必要はありません。
MockitoはDIフレームワークではなく、DIフレームワークでさえフィールドインジェクションよりもコンストラクタインジェクションを推奨しています。
したがって、テストするクラスの依存関係を設定するコンストラクタを宣言するだけです。
@Mock
private SomeService serviceMock;
private Demo demo;
/* ... */
@BeforeEach
public void beforeEach(){
demo = new Demo(serviceMock);
}
一般的な場合にMockito spy
を使用することは、ひどいアドバイスです。それはテストクラスを真っ直ぐではなく脆くし、エラーを起こしやすくします:本当にm笑されるものは何ですか?実際にテストされるのは何ですか?@InjectMocks
および@Spy
も、クラスの肥大化とクラスの責任の混在を助長するため、全体的な設計を損ないます。
ください spy()
javadocを読んでください 盲目的に使用する前に(強調は私のものではありません):
実オブジェクトのスパイを作成します。スパイは、スタブ化されていない限り、realメソッドを呼び出します。たとえば、レガシーコードを扱う場合は、実際のスパイを慎重に、ときどき使用する必要があります。
いつものように
partial mock warning
を読みます:オブジェクト指向プログラミングは、複雑さを個別の特定のSRPyオブジェクトに分割することにより、複雑さに取り組みます。部分モックはこのパラダイムにどのように適合しますか?そうではありません...部分的なモックは、通常、複雑さが同じオブジェクトの別のメソッドに移動したことを意味します。ほとんどの場合、これはアプリケーションの設計方法ではありません。ただし、部分モックが便利な場合はまれです:簡単に変更できないコードを処理する(サードパーティのインターフェイス、レガシーコードの暫定的なリファクタリングなど)ただし、新しいテスト駆動型のウェルモックには部分モックを使用しません。設計されたコード。