我正试着把头包裹在Arquillian周围,甚至可能在我的项目中开始使用它。我有一个简单的Java Web应用程序,它作为WAR部署到Tomcat。
在我的项目中,我定义了一个ServletContextListener
impl,以便在Tomcat启动和停止应用程序时可以执行代码。
我正在尝试编写一个使用ShrinkWrap的超简单 Arquillian测试类,并且:
ServletContextListener
检查);和此外,我实现ServletContextListener
的类称为AppLifecycleManager
:
public class AppLifeCycleManager implements ServletContextListener {
private String logLevel;
// Injected by Guice, but that's not really relevant for this question.
@Inject
private Logger logger;
// Getter and setter for logLevel and logger
@Override
public void contextInitialized(ServletContextEvent event) {
logLevel = System.getProperty("log.level");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
logger.info("Peacefully shutting down the application.");
}
}
到目前为止,这是我最好的尝试:
@RunWith(Arquillian.class)
public class MyFirstRealIntegrationTest {
@Deployment
public static Archive<?> createDeployment() {
// Haven't figured this part out yet, but for the sake of
// this question lets pretend this returns a properly-packaged
// WAR of my web app, the same that my Ant build currently produces.
}
@Test
public void shouldBeAbleToStartTomcatWithoutExceptions() {
// Given
Archive war = createDeployment();
// When - deploy war to Tomcat container
try {
// ??? how to access/init a Tomcat container?
TomcatContainer tomcat = new TomcatContainer(); // this is wrong
tomcat.start();
} catch(Throwable throwable) {
// Starting the container should not throw exceptions
Assert.fail();
}
}
@Test
public void shouldBeAbleToStopTomcatWithoutExceptions {
// Same setup as above test but stops tomcat and checks for
// thrown exceptions. Omitted for brevity.
}
@Test
public void shouldHaveAccessToSysPropsOnceRunning() {
// Here, deploy to the container and start it.
// Then, confirm that AppLifecycleManager correctly read
// the log.level system property.
// Given
Archive war = createDeployment();
TomcatContainer tomcat = new TomcatContainer();
// When - AppLifeycleManager should now read the system property
tomcat.start();
// Then - make sure log.level was set to "DEBUG" and that it was
// correctly read by AppLifeCycleManager.
Assert.assertTrue(war.getClass(AppLifeCycleManager.class)
.getLogLevel().equals("DEBUG"));
}
}
所以,根据我的方法,我立即遇到了几个问题:
war.getClass(AppLifeCycleManager.class).getLogLevel()
尝试访问“实时”类实例并检查其logLevel
属性的运行时值,但我知道这是错误的。所以我问:一个穿着战斗的Arquillian老手怎么会写这3个简单的测试,我怎样才能从JUnit测试中对我的“运行”web应用程序进行测试?提前谢谢。
答案 0 :(得分:2)
我不认为你应该在测试中处理tomcat的启动/关闭。如果您使用嵌入式tomcat容器,我会更容易:https://docs.jboss.org/author/display/ARQ/Tomcat+7.0+-+Embedded。在这种情况下,arquillian将处理tomcat的启动和关闭。
您应该在使用@Deployment注释的方法中创建部署。请阅读以下指南:http://arquillian.org/guides/getting_started/
答案 1 :(得分:1)
你快到了。 createDeployment
为您管理嵌入式容器的生命周期(自动启动和停止虚拟容器)。这样,你只关注测试本身。要编写集成测试,没有“框架”或“Arquillian API”来编写代码。您只需按照主代码的方式调用类和方法。
这里的关键是:您的测试实际上是在容器内运行的。如果发生异常,或者断言失败,Arquillian运行器会抛出异常并停止容器。对于您的代码示例,您正在测试是否可以读取系统属性:
@RunsWith(Arquillian.class)
public class MyArquillianTest {
@Deployment
public Archive<?> createDeployment() { ... }
@Test
public void shouldBeAbleToReadSysPropAtStartup() {
Assert.assertTrue(System.getProperty("log.level") != null);
}
}
请记住,Assert.assertTrue(System.getProperty("log.level") != null)
Arquillian将您的代码“传输”到您为其配置的容器中。因此断言实际上是在已部署的容器内运行。