2017-03-03 56 views
3

我有一個設備(設備必須解決,我使用彈簧移動設備)作爲參數休息控制器。單元測試給了我一個狀態415如何Junit的RestController,但與Spring Mobile(彈簧手機)

這裏是

@RequestMapping(method = RequestMethod.POST) 
public ResponseEntity<?> authenticationRequest(@RequestBody AuthenticationRequestDto authenticationRequest, 
     Device device) throws AuthenticationException { 

    Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
      authenticationRequest.getUsername(), authenticationRequest.getPassword())); 
    SecurityContextHolder.getContext().setAuthentication(authentication); 

    UserDetails userDetails = this.userDetailsService.loadUserByUsername(authenticationRequest.getUsername()); 

    String token = this.tokenGenerator.generateToken(userDetails, device); 

    return ResponseEntity.ok(new AuthenticationResponseDto(token)); 
} 

單元測試

ResultActions res = mockMvc.perform(post("/auth", authentication, device).contentType(TestUtil.APPLICATION_JSON_UTF8) 
      .content(TestUtil.convertObjectToJsonBytes(authentication))); 
    res.andExpect(status().isOk()); 
+0

這可能是有趣的把AuthenticationController'和'相關代碼' AuthenticationCont rollerTest'在這個問題。如果您更改了存儲庫中的代碼,它將使未來讀者的問題(和答案)失效。 – g00glen00b

+0

我會把代碼。謝謝 – neons

+0

確保你已經在某處添加了@ @ EnableWebMvc註解(可能是在一個配置類中),這對於Mock MVC的工作是必要的。 – g00glen00b

回答

1

基本上,我錯了我的配置。這是強制配置Web配置進行測試的方式與生產配置相同,但語法不同。那麼我對這個問題了解了很多有關MockMVC配置。

如果您想使用spring mobile進行單元測試,請使用以下解決方案。

頭等艙

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {WebTestConfig.class}) 
@WebAppConfiguration 
public class WebTestConfigAware { 

    @Autowired 
    private WebApplicationContext context; 

    protected MockMvc mockMvc; 

    @Autowired 
    private FilterChainProxy springSecurityFilterChain; 

    @Before 
    public void setup() { 
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); 
    DeviceResolverRequestFilter deviceResolverRequestFilter = new DeviceResolverRequestFilter(); 

    mockMvc = MockMvcBuilders.webAppContextSetup(context) 
     .addFilters(this.springSecurityFilterChain, deviceResolverRequestFilter).build(); 
    } 

} 

二等

@Configuration 
@EnableWebMvc 
@Import({RootTestConfig.class, WebCommonSecurityConfig.class}) 
public class WebTestConfig extends WebMvcConfigurerAdapter{ 


    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 
    argumentResolvers.add(new ServletWebArgumentResolverAdapter(new DeviceWebArgumentResolver())); 
    argumentResolvers.add(new SitePreferenceHandlerMethodArgumentResolver()); 
    } 
} 

和測試類

public class AuthenticationControllerTest extends WebTestConfigAware { 

    @Test 
    public void testAuthenticationRequest() throws Exception { 
    AuthenticationRequestDto authentication = new AuthenticationRequestDto(); 
    authentication.setUsername("admin"); 
    authentication.setPassword("Test1234"); 

    String jsonAuthentication = TestUtil.convertObjectToJsonString(authentication); 

    ResultActions res = mockMvc.perform(post("/auth") 
     .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).content(jsonAuthentication)); 

    res.andExpect(status().isOk()); 

    } 
0

代碼在您的測試類,你不適當地構建您的要求

// a couple of issues here explained below 
ResultActions res = mockMvc.perform(post("/auth", authentication, device).contentType(TestUtil.APPLICATION_JSON_UTF8) 
       .content(TestUtil.convertObjectToJsonBytes(authentication))); 

post("/auth", authentication, device)認證和設備被解釋爲路徑URI,因此它們不是neede在這裏,你的控制器URI沒有任何路徑URI變量。 如果你的意圖是傳遞2個對象作爲請求的主體,那麼你需要修改你的測試請求和你的控制器請求處理程序。你可以不通過2個對象作爲請求的身體,你需要封裝在一個對象中都像

class AuthenticationRequest { 
    private AuthenticationRequestDto authenticationDto; 
    private Device device; 

    // constructor, getters and setters 
} 

在你的控制器

@RequestMapping(method = RequestMethod.POST) 
    public ResponseEntity<?> authenticationRequest(@RequestBody AuthenticationRequest request) throws AuthenticationException { 
    AuthenticationRequestDto authenticationDto = request.getAuthenticationDto(); 
    Device device = request.getDevice(); 

    // .... 
} 

另外,在你測試你需要傳遞一個JSON對象字符串,你將它轉換爲字節(這就是爲什麼你得到一個415):

// note the change in the TestUtils, the method being called is convertObjectToJsonString (you'll need to add it) 
ResultActions res = mockMvc.perform(post("/auth").contentType(TestUtil.APPLICATION_JSON_UTF8) 
     .content(TestUtil.convertObjectToJsonString(new Authenticationrequest(authentication, device)))); 
+0

嗨,謝謝。你是對的!關於我的URI問題,但通常情況下,當我部署一個應用程序,使用POSTMAN我只是發送身份驗證(用戶和密碼),並通過Spring配置解決設備。 我不知道如果我需要MockMvc的更多配置或只是試圖嘲笑它 – neons

+0

太棒了! 你能否接受我的回答,讓其他人知道這個作品,如果他們面臨類似的問題? – artemisian

+0

當然。但我改變了評論。任何想法? – neons