2013-07-24 18 views
8

Ho una semplice classe PersonController che fornisce il metodo save() per mantenere l'oggetto dalla richiesta post http.Spring MockMvc redirectedUrl con pattern

package org.rw.controller; 

import java.sql.Timestamp; 
import java.util.List; 

import org.rw.entity.Person; 
import org.rw.service.PersonService; 
import org.rw.spring.propertyeditor.TimestampPropertyEditor; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.ui.ModelMap; 
import org.springframework.web.bind.WebDataBinder; 
import org.springframework.web.bind.annotation.InitBinder; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 


@Controller 
@RequestMapping(value="/person") 
public class PersonController { 

    private static final Logger logger = LoggerFactory.getLogger(PersonController.class); 

    @Autowired 
    private PersonService personService; 

    @Autowired 
    TimestampPropertyEditor timestampPropertyEditor; 


    @InitBinder 
    public void initBinder(WebDataBinder binder) { 
     binder.registerCustomEditor(Timestamp.class, "dob", timestampPropertyEditor); 
    } 


    @RequestMapping(value="/save", method=RequestMethod.POST) 
    public String save(Model model, Person person) { 
     Long personId = personService.save(person); 
     return "redirect:view/" + personId; 
    } 

} 

come metodo save() ritorna come return "redirect:view/" + personId;. Sarà diffrerente per ogni richiesta. potrebbe essere come "view/5" o "view/6" a seconda dell'ID dell'oggetto che è stato mantenuto.

Quindi ho una classe semplice per testare il controller sopra con spring mocking.

package org.rw.controller; 

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 

import org.junit.Test; 
import org.rw.service.UserService; 
import org.rw.test.SpringControllerTest; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.context.SecurityContextHolder; 
import org.springframework.security.core.userdetails.UserDetails; 

public class PersonControllerTest extends SpringControllerTest { 


    @Autowired 
    private UserService userService; 


    @Test 
    public void add() throws Exception { 
     mockMvc.perform(get("/person/add", new Object[0])).andExpect(status().isOk()); 
    } 


    @Test 
    public void save() throws Exception { 
     UserDetails userDetails = userService.findByUsername("anil"); 
     Authentication authToken = new UsernamePasswordAuthenticationToken (userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); 
     SecurityContextHolder.getContext().setAuthentication(authToken); 

     mockMvc.perform(
      post("/person/save", new Object[0]) 
       .param("firstName", "JunitFN") 
       .param("lastName", "JunitLN") 
       .param("gender", "M") 
       .param("dob", "11/02/1989") 
     ).andExpect(
       redirectedUrl("view") 
     ); 
    } 


} 

ora qui ho un problema che sta rifiutando redirectedUrl("view") valore "view/5". Ho provato redirectedUrl("view*") e redirectedUrl("view/*") ma non funziona.


Edit:

Qui ho ottenuto una soluzione alternativa come sotto

MvcResult result = mockMvc.perform(
    post("/person/save", new Object[0]) 
     .param("firstName", "JunitFN") 
     .param("lastName", "JunitLN") 
     .param("gender", "MALE") 
     .param("dob", "11/02/1989") 
).andExpect(
     //redirectedUrl("view") 
     status().isMovedTemporarily() 
).andReturn(); 

MockHttpServletResponse response = result.getResponse(); 

String location = response.getHeader("Location"); 

Pattern pattern = Pattern.compile("\\Aview/[0-9]+\\z"); 
assertTrue(pattern.matcher(location).find()); 

ma ancora Sto cercando il modo corretto.


aggiornamento:

ho postato lo stesso problema su spring jira here:

risposta

12

Dalla primavera 4.0 è possibile utilizzare redirectedUrlPattern come sottolineato dal Paulius Matulionis

partire dalla molla 3. x questo non è supportato immediatamente, ma puoi facilmente aggiungere risultati personalizzati

private static ResultMatcher redirectedUrlPattern(final String expectedUrlPattern) { 
    return new ResultMatcher() { 
     public void match(MvcResult result) { 
      Pattern pattern = Pattern.compile("\\A" + expectedUrlPattern + "\\z"); 
      assertTrue(pattern.matcher(result.getResponse().getRedirectedUrl()).find()); 
     } 
    }; 
} 

e usarlo come matcher build-in

mockMvc.perform(
    post("/person/save", new Object[0]) 
     .param("firstName", "JunitFN") 
     .param("lastName", "JunitLN") 
     .param("gender", "M") 
     .param("dob", "11/02/1989") 
).andExpect(
     redirectedUrlPattern("view/[0-9]+") 
); 
5

Dal 4.0 è disponibile nella primavera del sé.

Controllare here.

+0

e qui https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/web/servlet/result/MockMvcResultMatchers.html#redirectedUrl-java.lang.String- –

Problemi correlati