我在Mockito中使用MockMvc,大量使用Spring greenhouse样本。我有一个简单的控制器,它返回一个String视图名,如果有某种错误,则返回null。它在servlet环境中运行良好,但是当我尝试使用MockMvc standaloneSetup对控制器进行单元测试时,我得到了
javax.servlet.ServletException: Circular view path [register]: would dispatch back to the current handler URL [/register] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
这是我的控制器
@Controller
public class SignupController {
@RequestMapping(value="/register", method=RequestMethod.GET)
public RegistrationForm createNewRegForm(){
return new RegistrationForm();
}
/**
* Process a signup form submission.
* Delegate to a {@link SignupServiceImpl} to actually complete the signin transaction.
* Redirects the new member to the application home page on successful sign-in.
*/
@RequestMapping(value="/register", method=RequestMethod.POST)
public String signup(@Validated(Registration.class) RegistrationForm form, BindingResult formBinding) {
if(formBinding.hasErrors())
return null;
boolean success = signupHelper.signup(form.getUser(), formBinding);
return (!formBinding.hasErrors() && success) ? "redirect:/" : null;
}
}
并且测试失败:
public void signup_duplicateEmail() throws Exception {
AccountManager accountRepository = mock(AccountManager.class);
AccountAuthUtils authorization = mock(AccountAuthUtils.class);
when(accountRepository.createAccount(any(User.class))).thenThrow(new EmailAlreadyOnFileException("roy@clarkson.com"));
SignupServiceImpl gateway = new SignupServiceImpl(accountRepository, authorization);
SignupController signupController = new SignupController(gateway);
MockMvc mockMvc = standaloneSetup(signupController).build();
mockMvc.perform(post("/register").contentType(APPLICATION_FORM_URLENCODED)
.param("user.username","habuma")
.param("user.email","roy%40clarkson.com")
.param("user.password", "letmein1")
.param("confirmPassword", "letmein1"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.forwardedUrl("/register.do"))
.andExpect(MockMvcResultMatchers.model().hasErrors())
.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("registrationForm", "user.email"));
}
一个简单的解决方法是在控制器中为失败返回“/register.do”而不是null,但我不想更改我的代码以使测试工作。
答案 0 :(得分:1)
我的猜测是造成这种差异的原因是因为在制作中你已经将ViewResolver配置为使用“/ WEB-INF /”和可能的后缀。在您的独立测试设置中,您没有添加ViewResolver,因此默认情况下只需获取视图名称并将其转换为路径,此时它会意识到它与请求路径相同。
至于.do的文档,你有一点意见,我们很快会添加一些内容,track here。
答案 1 :(得分:0)
好的,经过几个小时的折断,我明白了。
基本上,只要初始网址与结束网址相同,它就会出现此问题。但是你可以通过发帖(“register.do”)(这是servlet的作用)来欺骗它,并检查它是否返回“register”。因此,我的解决方案是:
mockMvc.perform(post("/register.do").contentType(APPLICATION_FORM_URLENCODED)
.param("user.username","habuma")
.param("user.email","roy%40clarkson.com")
.param("user.password", "letmein1")
.param("confirmPassword", "letmein1"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.forwardedUrl("register"))
现在它适用于测试和服务器环境。
P.S。我希望所有这些.do的东西都有很好的文件。经过多年的努力,我从未真正理解它。