讓我們通過Hibernate JPA通過DAO來想象使用MySql的Spring 3.1 web mvc應用程序。如何使用@ContextConfiguration在本地和內存中測試Web Spring應用程序?
必須爲控制器編寫測試,而不必部署應用程序並使用內存數據庫(例如hsqldb:mem
)。換句話說,應該能夠在本地PC上運行測試。
這是如何實現的?有人可以提供一個詳細的例子來說明如何爲這樣的控制器編寫測試嗎? @ContextConfiguration
如何配置?如何檢索本地測試用的WebApplicationContext
?應該保持一個hibernate-test.cfg.xml
?
更新
我不是說只對單元測試,我說的是集成測試。
解決方案
爲了讓這個完整的肖恩·帕特里克·弗洛伊德的回答之上,這裏是從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的,很容易也要注入基於內存數據庫的實現。
好吧,讓我們假設我分開了web層和持久層測試。並且,假設我專注於Web層測試,一些控制器仍然會嘗試持久化對象(不在我的示例中,但我的意思是在大多數應用程序中)。你是說我應該爲我的內存數據庫有一個單獨的休眠配置?如果是,我該如何通知測試使用此配置? – JVerstry 2012-07-10 12:55:46
@JVerstry「一些控制器仍然會嘗試持久化對象」,而這正是使應用程序無法測試的原因:當一層做得比應該多時。 Web層不應該意識到持久性。它應該使用服務層來做到這一點。現在你只需要模擬你的服務層來測試你的Web控制器,模擬你的持久層來測試服務層等。測試一層並模擬下一層。 – 2012-07-10 13:00:31