如何通过"找不到ModelAndView"修复测试失败?

Pav*_*nko 5 java unit-testing spring-mvc applicationcontext spring-boot

这个类位于我的测试层次结构的顶部:

@TestPropertySource("/test.properties")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class ApplicationAbstractTest {
}
Run Code Online (Sandbox Code Playgroud)

还有更少的测试类:

@WebAppConfiguration
@ActiveProfiles("mysql")
abstract public class AbstractControllerTest extends ApplicationAbstractTest {

    protected MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @PostConstruct
    private void postConstruct() {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(webApplicationContext)
                .apply(springSecurity())
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

JsonUserServiceTest:

@ActiveProfiles("json")
public class JsonUserServiceTest extends ApplicationAbstractTest {
    @Before
    public void setUp() throws Exception {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

ContactControllerTest:

public class ContactControllerTest extends AbstractControllerTest {
    @Test
    public void testGet() throws Exception {
        mockMvc.perform(get("/update-" + ID + "-contact")
                .with(userAuth(USER)))
//                .andExpect(status().isOk())
                .andDo(print())
                .andExpect(view().name("details"))
                .andExpect(forwardedUrl("/WEB-INF/jsp/details.jsp"));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,当我跑步ContactControllerTest时 - 它是成功的,print方法告诉我:

Handler:
             Type = com.telecom.web.ContactController
           Method = public java.lang.String com.myApp.web.ContactController.details(java.lang.Integer,org.springframework.ui.ModelMap)
Run Code Online (Sandbox Code Playgroud)

但是,当我运行所有测试时,JsonUserServiceTest首先运行,ContactControllerTest失败.并print显示:

Handler:
             Type = null
...
java.lang.AssertionError: No ModelAndView found
Run Code Online (Sandbox Code Playgroud)

配置有什么问题?或者如何排除故障?

UPD:与此同时,这样的测试总是很好:

public class UserControllerTest extends AbstractControllerTest {
    @Test
    public void testRegister() throws Exception {
        mockMvc.perform(get("/register"))
                .andDo(print())
                .andExpect(view().name("profile"))
                .andExpect(forwardedUrl("/WEB-INF/jsp/profile.jsp"));
    }
}
Run Code Online (Sandbox Code Playgroud)

UPD:我正在测试控制器的方法:

@GetMapping("/update-{id}-contact")
public String details(@PathVariable Integer id, ModelMap model) {
    Integer userId = AuthorizedUser.id();
    LOG.info("get contact {} for User {}", id, userId);
    Contact contact = service.get(id, userId);
    model.addAttribute("contact", contact);
    return "details";
}
Run Code Online (Sandbox Code Playgroud)

我也有这样的豆子:

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/WEB-INF/jsp/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}
Run Code Online (Sandbox Code Playgroud)

UPD:我尝试在单独的类中配置mockMvc:

@Configuration
public class TestConfig {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Bean
    public MockMvc mockMvc() {
        return MockMvcBuilders
                .webAppContextSetup(webApplicationContext)
                .apply(springSecurity())
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

并在此处添加:

@WebAppConfiguration
@ContextConfiguration(classes = {TestConfig.class})
@ActiveProfiles("mysql")
abstract public class AbstractControllerTest extends ApplicationAbstractTest {
Run Code Online (Sandbox Code Playgroud)

但我收到了:

java.lang.IllegalStateException:springSecurityFilterChain不能为null.确保使用名称为springSecurityFilterChain的Bean实现Filter,或者注入要使用的Filter.

Abd*_*man 5

警告消息不会导致测试用例失败。它只是说实体管理器工厂注册了两次。仅当您使用相同的实体管理器工厂对应用程序进行集群时,这才会成为问题。对于测试用例运行来说,这不是一个令人担忧的问题。

测试用例失败的根本原因就在这两行

 .andExpect(view().name("details"))
 .andExpect(forwardedUrl("/WEB-INF/jsp/details.jsp"));
Run Code Online (Sandbox Code Playgroud)

请检查项目是否有名为“details”的视图,转发的url为“/WEB-INF/jsp/details.jsp”

更新

你能试试这个吗

@Configuration
public class TestConfig {


@Autowired
private Filter springSecurityFilterChain;

@Autowired
private WebApplicationContext webApplicationContext;

@Bean
public MockMvc mockMvc() {
    return MockMvcBuilders
            .webAppContextSetup(webApplicationContext)
            .apply(springSecurityFilterChain)
            .build();
}
}
Run Code Online (Sandbox Code Playgroud)