8

今日からオフィスで Spring Test MVC Framework の勉強を始めました。便利そうに見えますが、すぐに重大な問題に直面します。グーグルで数時間を費やしましたが、私の問題に関連するものは何も見つかりませんでした。

これが私の非常に単純なテストクラスです:

import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = WebAppContext.class)
public class ControllerTests {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = webAppContextSetup(wac).build();
    }

    @Test
    public void processFetchErrands() throws Exception {
        mockMvc.perform(post("/errands.do?fetchErrands=true"))
               .andExpect(status().isOk())
               .andExpect(model().attribute("errandsModel", allOf(
                   hasProperty("errandsFetched", is(true)),
                   hasProperty("showReminder", is(false)))));
    }
}

ifテストは次のコントローラーに到達しますが、適切に承認されていないため、最初の句で失敗します。

@RequestMapping(method = RequestMethod.POST, params="fetchErrands")
public String processHaeAsioinnit(HttpSession session, HttpServletRequest request, ModelMap modelMap,
                                  @ModelAttribute(ATTR_NAME_MODEL) @Valid ErrandsModel model,
                                  BindingResult result, JopoContext ctx) {
  if (request.isUserInRole(Authority.ERRANDS.getCode())) {
    return Page.NO_AUTHORITY.getCode();
  }

  [...]
}

MockHttpServletRequestによって作成された のユーザー ロールを追加MockMvcRequestBuilders.post()して、コントローラーの権限チェックを通過できるようにするにはどうすればよいですか?

MockHttpServletRequestmethod があることは知っていaddUserRole(String role)ますがMockMvcRequestBuilders.post()、 a を返すためMockHttpServletRequestBuilder、 を手に入れることMockHttpServletRequestができず、そのメソッドを呼び出すことができません。

Spring ソースを確認するMockHttpServletRequestBuilderと、ユーザー ロールに関連するメソッドがなくMockHttpServletRequest.addUserRole(String role)、そのクラスで呼び出されることもないため、ユーザー ロールをリクエストに追加するように指示する方法がわかりません。

私が考えることができるのは、フィルタ チェーンにカスタム フィルタを追加し、HttpServletRequestWrapperそこから の実装を提供するカスタムを呼び出すisUserInRole()ことだけですが、そのような場合は少し極端に思えます。確かに、フレームワークはより実用的なものを提供する必要がありますか?

4

5 に答える 5

2

Spring MVC Test には、このような場合にリクエスト資格情報をモックできる principal() メソッドがあります。これは、いくつかのモック資格情報が設定されているテストの例です。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath:spring/mvc-dispatcher-servlet.xml")
public class MobileGatewayControllerTest {

private MockMvc mockMvc;

@Autowired
private WebApplicationContext wac;  

@Autowired
private Principal principal;

@Autowired
private MockServletContext servletContext;

@Before 
public void init()  {
    mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}


@Test
public void testExampleRequest() throws Exception {

    servletContext.declareRoles("ROLE_1");

    mockMvc.perform(get("/testjunit")
    .accept(MediaType.APPLICATION_JSON)
    .principal(principal))
    .andDo(print())
    .andExpect(status().isOk())
    .andExpect(content().contentType("application/json"))
    .andExpect(jsonPath("$.[1]").value("test"));
}

}

これは、モック プリンシパルを作成する方法の例です。

@Configuration
public class SetupTestConfig {

@Bean
public Principal createMockPrincipal()  {
    Principal principal = Mockito.mock(Principal.class);
    Mockito.when(principal.getName()).thenReturn("admin");  
    return principal;
}

}

于 2014-01-02T15:19:08.953 に答える