如何使用@ContextConfiguration在本地和内存中测试Web Spring应用程序?

时间:2012-07-10 12:32:07

标签: java spring unit-testing spring-mvc

让我们设想一个Spring 3.1 web mvc应用程序,通过DAO的Hibernate JPA使用MySql。

必须为控制器编写测试而不部署应用程序并使用内存数据库(例如hsqldb:mem)。换句话说,一个人应该能够在本地PC上运行测试。

如何实现这一目标?有人可以提供一个如何为这样的控制器编写测试的详细示例吗?应该如何配置@ContextConfiguration?如何在本地检索WebApplicationContext以进行测试?应该保持hibernate-test.cfg.xml

更新

我不是只讨论单元测试,我说的是集成测试。

解决方案

为了在Sean Patrick Floyd的回答之上完成这一点,这是一个灵感来自here的解决方案:

服务示例:

public interface MarkingService {
    public String markItem(String item);
}

使用服务的控制器示例

@Controller  
public class TestableController {

    @Autowired
    private MarkingService markerService;

    @RequestMapping(value = "mark/{name}")  
    public String mark(Model ui, @PathVariable String name){  

        String value = this.markerService.markItem(name);
        ui.addAttribute("mark-value", value);

        return "mark-show";  

    }  

}

测试控制器的服务模拟:

public class MarkingServiceMock implements MarkingService {

    @Override
    public String markItem(String item) {
        return "mockValue";
    }

}

用于测试配置的Config对象:

@Configuration
public class TestableControllerConfig {

    // We return a mock to test the controller layer
    @Bean
    public MarkingService markingService() {
        return new MarkingServiceMock();
    }

}

控制器测试:

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(classes={TestableControllerConfig.class})
public class TestableControllerTest {

    // Will be injected with TestableControllerConfig.markingService()
    @Autowired
    private MarkingService markerService;

    @Test
    public void testController() {

        // ...

    }

}

假设服务层依赖于DAO,那么很容易注入基于内存数据库的实现。

1 个答案:

答案 0 :(得分:1)

通常,您不会测试整个设置。编写Web层测试并模拟其中的持久层。为服务和持久层编写单独的测试。

如果您要测试网络控制器,请使用ModelAndViewAssertthe Mock versions of HttpServletRequest etc.

另一方面,如果您想测试整个设置,请使用HtmlUnit,Selenium等运行自动化Web测试,但是在您真实部署的应用程序上进行(当然是非公开安装)。

但在我看来,如果你想测试大局,你需要测试真实的东西。大规模嘲弄变得非常混乱。