简体   繁体   English

Spring MockMvc redirectedUrl with pattern

[英]Spring MockMvc redirectedUrl with pattern

I have a simple PersonController class that provides save() method to persist the object from http post request. 我有一个简单的PersonController类,它提供了save()方法来save()来自http post请求的对象。

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

}

As the save() method returns as return "redirect:view/" + personId; save()方法返回为return "redirect:view/" + personId; . It will be diffrerent for every request. 每个请求都会有所不同。 it may be like "view/5" or "view/6" depending on the id of the object that has been persisted. 它可能类似于"view/5""view/6"具体取决于已持久化的对象的id。

Then i have a simple class to test the above controller with 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")
        );
    }


}

now here i have a problem that redirectedUrl("view") is rejecting value "view/5" . 现在我有一个问题, redirectedUrl("view")拒绝值"view/5" I have tried redirectedUrl("view*") and redirectedUrl("view/*") but its not working. 我尝试过redirectedUrl("view*")redirectedUrl("view/*")但它无法正常工作。


Edit : 编辑:

Here I have got a workaround as per below 在这里,我有一个解决方法,如下所示

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

but still i am looking for the proper way. 但我仍在寻找正确的方法。


update: 更新:

I have posted the same issue on spring jira here : 我在春季jira上发布了同样的问题:

Since spring 4.0 you can use redirectedUrlPattern as pointed by Paulius Matulionis 由于弹簧4.0可以使用redirectedUrlPattern为指向的Paulius Matulionis

As of spring 3.x this is not supported out of the box but you can easily add you custom result matcher 从Spring 3.x开始,这不支持开箱即用,但您可以轻松添加自定义结果匹配器

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

And use it like build-in matcher 并像内置匹配器一样使用它

 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]+")
 );

Since 4.0 it is available in Spring itself. 4.0它就可以在Spring中使用。

Please check here . 点击这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM