データベースから読み取ってJSON応答を返す単純なSpring Boot Webアプリがあります。次のテスト構成があります。
@RunWith(SpringRunner.class)
@SpringBootTest(classes=MyApplication.class, properties={"spring.config.name=myapp"})
@AutoConfigureMockMvc
public class ControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private ProductRepository productRepo;
@MockBean
private MonitorRepository monitorRepo;
@Before
public void setupMock() {
Mockito.when(productRepo.findProducts(anyString(), anyString()))
.thenReturn(Arrays.asList(dummyProduct()));
}
@Test
public void expectBadRequestWhenNoParamters() throws Exception {
mvc.perform(get("/products"))
.andExpect(status().is(400))
.andExpect(jsonPath("$.advice.status", is("ERROR")));
}
//other tests
}
アプリケーションのメイン構成で構成されているDataSource Beanがあります。テストを実行すると、データソースがJNDIから取得されるため、Springはコンテキストをロードしようとして失敗します。一般に、私はリポジトリをモック化しているので、このテスト用のデータソースの作成は避けたいです。
単体テストの実行時にデータソースの作成をスキップすることはできますか?
データベース作成スクリプトには特定の構造があり、classpath:schema.sqlから簡単に実行できないため、メモリ内のテスト用データベースはオプションではありません。
編集データソースはMyApplication.class
で定義されています
@Bean
DataSource dataSource(DatabaseProeprties databaseProps) throws NamingException {
DataSource dataSource = null;
JndiTemplate jndi = new JndiTemplate();
setJndiEnvironment(databaseProps, jndi);
try {
dataSource = jndi.lookup(databaseProps.getName(), DataSource.class);
} catch (NamingException e) {
logger.error("Exception loading JNDI datasource", e);
throw e;
}
return dataSource;
}
構成クラスをロードしているので、_MyApplication.class
_データソースBeanが作成されます。テストで使用されていない別のBeanにデータソースを移動してみてください。テスト用にロードされたすべてのクラスがデータソースに依存していないことを確認してください。
または
テストで、_@TestConfiguration
_でマークされた構成クラスを作成し、SpringBootTest(classes=TestConfig.class)
モックデータソースに含めます。
_@Bean
public DataSource dataSource() {
return Mockito.mock(DataSource.class);
}
_
ただし、接続のためにこのモック化されたdatasouceへのメソッド呼び出しがnullを返すため、これは失敗する可能性があります。その場合、メモリ内データソースを作成してから、jdbcTemplateと残りの依存関係をモックする必要があります。
データソースを @MockBean
も:
@MockBean
private DataSource dataSource
これにより、Springが置換ロジックを実行し、プロダクションコードBeanの作成が実行されない(JNDIルックアップがない)という利点があります。