私はこのコンストラクタを持つSpring MVC @Controller
を持っています:
@Autowired
public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/}
このコントローラーのスタンドアロンユニットテストを作成します。
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
private String myProperty = "my property value";
@InjectMocks
private AbcController controllerUnderTest;
/* tests */
}
Stringプロパティを挿入する@InjectMocks
を取得する方法はありますか?文字列は不変であるため、モックできないことはわかっていますが、通常の文字列をここに挿入することはできますか?
この場合、@InjectMocks
はデフォルトでnullを挿入します。 @Mock
は、myProperty
に設定すると例外的にスローされます。 「モックではなく、この正確なオブジェクトを挿入する」という意味の、私が見逃した別の注釈はありますか?
Mockitoでこれを行うことはできません。自分で言ったように、String
はfinal
であり、モックできないからです。
realオブジェクトで機能する@Spy
アノテーションがありますが、@Mock
と同じ制限があるため、スパイできませんString
で。
モックやスパイを行わずにその値を注入するようにMockitoに指示する注釈はありません。しかし、それは良い機能でしょう。おそらく Mockito Githubリポジトリ で提案してください。
コードを変更したくない場合は、コントローラーを手動でインスタンス化する必要があります。
純粋な注釈ベースのテストを行う唯一の方法は、コントローラーをリファクタリングすることです。 1つのプロパティのみを含むカスタムオブジェクト、または複数のプロパティを持つ構成クラスを使用できます。
@Component
public class MyProperty {
@Value("${my.property}")
private String myProperty;
...
}
これをコントローラーに注入できます。
@Autowired
public AbcController(XyzService xyzService, MyProperty myProperty) {
...
}
これをモックしてインジェクトできます。
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
@Mock
private MyProperty myProperty;
@InjectMocks
private AbcController controllerUnderTest;
@Before
public void setUp(){
when(myProperty.get()).thenReturn("my property value");
}
/* tests */
}
これは簡単なことではありませんが、少なくともスタブを少し追加するだけで、純粋な注釈ベースのテストを実行できます。
Mockitoでこれを行うことはできませんが、Apache Commonsには実際には、組み込みユーティリティの1つを使用してこれを行う方法があります。次のように、Mockitoが残りのモックを注入した後、テストケースが実行される前に実行されるJUnitの関数にこれを配置できます。
@InjectMocks
MyClass myClass;
@Before
public void before() throws Exception {
FieldUtils.writeField(myClass, "fieldName", fieldValue, true);
}
その場合は、@ InjectMocksを使用しないでください。
行う:
@Before
public void setup() {
controllerUnderTest = new AbcController(mockXyzService, "my property value");
}
Springを使用しているので、org.springframework.test.util.ReflectionTestUtils
から spring-test
モジュール。オブジェクトのフィールドまたはクラスの静的フィールドの設定を(他のユーティリティメソッドと共に)きちんとラップします。
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
@InjectMocks
private AbcController controllerUnderTest;
@Before
public void setUp(){
ReflectionTestUtils.setField(controllerUnderTest, "myProperty",
"String you want to inject");
}
/* tests */
}
使用できるのはこれです:org.mockito.internal.util.reflection.Whitebox
Testクラスの「before」メソッドで、Whitebox.setInternalStateメソッドを使用して、必要な文字列を指定します
@Before
public void setUp(){
Whitebox.setInternalState(controllerUnderTest, "myProperty", "The string that you want"); }