新しいSpring Boot 1.4 _@WebMvcTest
_でさまざまな方法でMockMVc
をセットアップするための作業コードはほとんどありません。 standaloneSetupアプローチを理解しています。私が知りたいのは、MockMvc
からWebApplicationContext
までの設定とMockMvc
の自動配線による設定の違いです。
コードスニペット1:WebApplicationContextセットアップを介したMockMvc
_@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ProductController.class)
public class ProductControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@MockBean
private ProductService productServiceMock;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testShowProduct() throws Exception {
Product product1 = new Product();
/*Code to initialize product1*/
when(productServiceMock.getProductById(1)).thenReturn(product1);
MvcResult result = mockMvc.perform(get("/product/{id}/", 1))
.andExpect(status().isOk())
/*Other expectations*/
.andReturn();
}
}
_
WebMvcTest
APIドキュメントによると、デフォルトでは、@ WebMvcTestアノテーションが付けられたテストは、Spring SecurityとMockMvcを自動構成します。そのため、ここでは401 Unauthorizedステータスコードが必要ですが、テストは200ステータスコードで合格します。
次に、MockMvc
の自動配線を試みましたが、@AutoConfigureMockMvc(secure=false)
を追加するか_@WebMvcTest
_アノテーションを更新してセキュリティを無効にしない限り、テストは401 Unauthorizedステータスコードで失敗します。
_@WebMvcTest(controllers = IndexController.class, secure = false)
_
以下は、明示的にセキュリティを無効にした後にのみ渡すコードです。
コードスニペット2:自動配線によるMockMvc
_@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ProductController.class)
@AutoConfigureMockMvc(secure=false)
public class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@MockBean
private ProductService productServiceMock;
@Test
public void testShowProduct() throws Exception {
Product product1 = new Product();
/*Code to initialize product1*/
when(productServiceMock.getProductById(1)).thenReturn(product1);
MvcResult result = mockMvc.perform(get("/product/{id}/", 1))
.andExpect(status().isOk())
/*Other expectations*/
.andReturn();
}
}
_
だから私の質問は:
MockMvc
が自動配線したときに、コードスニペット1が401 Unauthorizedステータスコードエラーを報告しなかった理由。また、公式ドキュメントの内容を繰り返しますデフォルトでは、@ WebMvcTestアノテーションが付けられたテストは、Spring SecurityとMockMvcも自動構成します。しかし、この場合は表示されます_@WebMvcTest
_は、Spring Securityの自動設定とは関係ありません(コードスニペット1が401エラーなしで渡されるため)。最後に、MockMvc
の設定方法を説明します。私はここで正しいですか?
両方のアプローチの違い/目的は何ですか?
@AutoConfigureMockMvc(secure=false)
を介したセキュリティの無効化は、@WebMvcTest(controllers = IndexController.class, secure = false)
を介した無効化とどのように異なりますか。どのアプローチが推奨されますか、それをいつ(またはどこで)使用しますか?
私も同様の問題に遭遇します。 @WebMvcTestは、基本認証でSpring Securityを自動構成しますが、WebSecurityConfigurerAdapterを拡張するWebSecurityConfigクラスがあります。このクラスでは、基本認証を無効にし、トークンベースセキュリティを構成しました。つまり、WebSecurityConfigクラスはSpring Securityの構成には使用されません。
この問題を解決するために、ユニットテストクラスに@ContextConfigurationを追加し、WebSecurityConfigクラスの依存関係のモックを追加しました。
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = CategoryRestService.class)
@ContextConfiguration(classes={MjApplication.class, WebSecurityConfig.class})
public class CategoryRestServiceTest {
@MockBean
private CategoryRepository repository;
@MockBean
CurrentUserDetailsService currentUserDetailsService;
@MockBean
TokenAuthProvider tokenAuthProvider;
@Autowired
MockMvc mockMvc;
private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
@Test
public void getCategories() throws Exception {
Category category1 = new Category();
category1.setName("Test Category 1");
category1.setId(1L);
Category category2 = new Category();
category2.setName("Test Category 2");
category2.setId(2L);
List<Category> categoryList = new ArrayList<Category>();
categoryList.add(category1);
categoryList.add(category2);
given(this.repository.findAll())
.willReturn(categoryList);
mockMvc.perform(get("/public/rest/category"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[0].name", is("Test Category 1")))
.andExpect(jsonPath("$[1].id", is(2)))
.andExpect(jsonPath("$[1].name", is("Test Category 2")));
}
}
Githubのこの問題によると
https://github.com/spring-projects/spring-boot/issues/5476
@WebMvcTestはデフォルトで自動設定します。spring-security-testがクラスパスにある場合の基本認証
質問に答える:
デフォルトでは、@ WebMvcTestアノテーションが付けられたテストは、Spring SecurityおよびMockMvcを自動構成します(HtmlUnit WebClientおよびSelenium WebDriverのサポートを含む)。 MockMVCのよりきめ細かい制御には、@ AutoConfigureMockMvcアノテーションを使用できます。
これが直接関係するかどうかはわかりませんが、 顕著なバグ があります。ここで、スプリングブーツと@WebMvcTest
、カスタム@EnableWebSecurity
構成クラスは無視されます。いくつかの回避策がバグレポートに記載されています。私は使用しています:
@WebMvcTest(includeFilters = @Filter(classes = EnableWebSecurity.class))