2013-07-24 10 views
8

Mam prostą klasę PersonController, która zapewnia metodę save() utrwalania obiektu z żądania postu HTTP.Spring MockMvc przekierowywany z wzorcem

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; 
    } 

} 

Jako save() sposób powraca jak return "redirect:view/" + personId;. Będzie on różny dla każdego żądania. może być jak "view/5" lub "view/6" w zależności od identyfikatora obiektu, który został utrwalony.

Następnie mam prostą klasę do testowania powyższego kontrolera z kpiną wiosenną.

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") 
     ); 
    } 


} 

teraz tutaj mam problem, że redirectedUrl("view") odrzuca wartości "view/5". Próbowałem redirectedUrl("view*") i redirectedUrl("view/*"), ale nie działa.


Edit:

Tutaj mam obejście zgodnie poniżej

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()); 

ale nadal szukam właściwy sposób.


zmiana:

Pisałem ten sam problem na spring jira here:

Odpowiedz

12

Od wiosny 4.0 można użyć redirectedUrlPattern jak wskazał przez Paulius Matulionis

Jako wiosny 3. x to nie jest obsługiwane od razu po wyjęciu z pudełka, ale możesz łatwo dodać niestandardowy matematyczny wynik

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()); 
     } 
    }; 
} 

i używać go jak wbudowany dopasowującego

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

Od 4.0 jest dostępny w samej wiosny.

Proszę sprawdzić here.

+0

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

Powiązane problemy