我正在开发一个Spring MVC休息服务,为此我也试图建立JBehave。这是一个带有单个模块的Maven项目,JBehave代码生活在该模块的test
范围内。我的问题是我的样本测试(这只是一个空的测试)失败了NPE。我期待看到测试通过,以便我知道JBehave设置正确。你能看一下我所得到的东西,看看你是否可以帮助我找出造成NPE的原因?
首先,我的maven配置的相关部分:
<properties>
<jbehave.version>4.0.4</jbehave.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-core</artifactId>
<version>${jbehave.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-spring</artifactId>
<version>${jbehave.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jbehave.site</groupId>
<artifactId>jbehave-site-resources</artifactId>
<version>3.1.1</version>
<scope>test</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-core</artifactId>
<version>${jbehave.version}</version>
<classifier>resources</classifier>
<type>zip</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<scope>test</scope>
<testSourceDirectory>${basedir}/src/test/java/</testSourceDirectory>
<testClassesDirectory>${project.build.directory}/test-classes/</testClassesDirectory>
<includes>
<include>com/mycompany/myproject/test/behavior/steps/*.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-maven-plugin</artifactId>
<version>${jbehave.version}</version>
<configuration>
<scope>test</scope>
</configuration>
<executions>
<execution>
<id>unpack-view-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-view-resources</goal>
</goals>
</execution>
<execution>
<id>run-stories-as-embeddables</id>
<phase>integration-test</phase>
<configuration>
<scope>test</scope>
<includes>
<include>com/mycompany/myproject/test/behavior/steps/*.java</include>
</includes>
<systemProperties>
<property>
<name>java.awt.headless</name>
<value>true</value>
</property>
</systemProperties>
</configuration>
<goals>
<goal>run-stories-as-embeddables</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>
</build>
我通过mvn clean integration-test -e
运行我的测试,我得到了这个输出:
$ mvn clean integration-test -e
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject 0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ MyProject ---
[INFO] Deleting C:\Users\mylogin\myproject\target
[INFO]
[INFO] --- jbehave-maven-plugin:4.0.4:unpack-view-resources (unpack-view-resources) @ MyProject ---
[INFO] Unpacked C:\Users\mylogin\.m2\repository\org\jbehave\site\jbehave-site-resources\3.1.1\jbehave-site-resources-3.1.1.zip to C:\Users\mylogin\myproject\target\jbehave\view
[INFO] Unpacked C:\Users\mylogin\.m2\repository\org\jbehave\jbehave-core\4.0.4\jbehave-core-4.0.4-resources.zip to C:\Users\mylogin\myproject\target\jbehave\view
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ MyProject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 18 resources
[INFO] Copying 6 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ MyProject ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 62 source files to C:\Users\mylogin\myproject\target\classes
... omitted ...
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ MyProject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 6 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ MyProject ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 12 source files to C:\Users\mylogin\myproject\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ MyProject ---
[INFO] Surefire report directory: C:\Users\mylogin\myproject\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps
Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=true,ignoreFailureInView=false,verboseFailures=true,verboseFiltering=false,storyTimeouts=300,threads=1,failOnStoryTimeout=false]
Running story com/mycompany/myproject/test/behavior/steps/sample_rest_call_with_invalid_account_steps.story
Generating reports view to 'C:\Users\mylogin\myproject\target\jbehave' using formats '[stats, ide_console, txt, html]' and view properties '{navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, reports=ftl/jbehave-reports.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl, decorated=ftl/jbehave-report-decorated.ftl, maps=ftl/jbehave-maps.ftl}'
Reports view generated with 2 stories (of which 1 pending) containing 1 scenarios (of which 1 pending)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.326 sec - in com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-war-plugin:3.0.0:war (default-war) @ MyProject ---
[INFO] Packaging webapp
[INFO] Assembling webapp [MyProject] in [C:\Users\mylogin\myproject\target\mywarname##0.1]
[INFO] Processing war project
[INFO] Copying webapp resources [C:\Users\mylogin\myproject\src\main\webapp]
[INFO] Webapp assembled in [484 msecs]
[INFO] Building war: C:\Users\mylogin\myproject\target\mywarname##0.1.war
[INFO]
[INFO] --- spring-boot-maven-plugin:1.3.5.RELEASE:repackage (default) @ MyProject ---
[INFO]
[INFO] --- jbehave-maven-plugin:4.0.4:run-stories-as-embeddables (run-stories-as-embeddables) @ MyProject ---
[INFO] Running stories as embeddables using embedder Embedder[storyMapper=StoryMapper,embedderMonitor=MavenEmbedderMonitor,classLoader=EmbedderClassLoader[urls=[/C:/Users/mylogin/Projects/AQ/aqservices/target/test-classes/, /C:/Users/mylogin/Projects/AQ/aqservices/target/classes/, spring-boot-starter-tomcat-1.3.5.RELEASE.jar, tomcat-embed-core-8.0.33.jar, tomcat-embed-el-8.0.33.jar, tomcat-embed-logging-juli-8.0.33.jar, tomcat-embed-websocket-8.0.33.jar, spring-ws-core-2.3.0.RELEASE.jar, spring-xml-2.3.0.RELEASE.jar, spring-aop-4.2.6.RELEASE.jar, spring-beans-4.2.6.RELEASE.jar, spring-core-4.2.6.RELEASE.jar, spring-oxm-4.2.6.RELEASE.jar, spring-web-4.2.6.RELEASE.jar, spring-webmvc-4.2.6.RELEASE.jar, spring-boot-starter-1.3.5.RELEASE.jar, spring-boot-1.3.5.RELEASE.jar, spring-boot-autoconfigure-1.3.5.RELEASE.jar, snakeyaml-1.16.jar, spring-boot-starter-log4j-1.3.7.RELEASE.jar, jcl-over-slf4j-1.7.21.jar, jul-to-slf4j-1.7.21.jar, slf4j-log4j12-1.7.21.jar, log4j-1.2.17.jar, spring-orm-4.3.2.RELEASE.jar, spring-jdbc-4.2.6.RELEASE.jar, spring-tx-4.2.6.RELEASE.jar, spring-data-commons-1.12.2.RELEASE.jar, spring-context-4.2.6.RELEASE.jar, spring-expression-4.2.6.RELEASE.jar, spring-context-support-4.1.4.RELEASE.jar, spring-test-4.2.6.RELEASE.jar, spring-security-core-4.1.1.RELEASE.jar, aopalliance-1.0.jar, spring-security-web-4.1.1.RELEASE.jar, spring-security-config-4.1.1.RELEASE.jar, jstl-1.2.jar, wsdl4j-1.6.3.jar, aspectjweaver-1.8.9.jar, jasypt-1.9.2.jar, xstream-1.4.9.jar, xmlpull-1.1.3.1.jar, xpp3_min-1.1.4c.jar, bcprov-jdk16-1.46.jar, org.apache.commons.io-2.4.jar, commons-io-2.4.jar, slf4j-api-1.7.21.jar, commons-lang-2.6.jar, mail-1.4.jar, activation-1.1.jar, dozer-5.5.1.jar, commons-beanutils-1.9.2.jar, commons-lang3-3.2.1.jar, jregex-1.2_01.jar, tomcat-embed-jasper-8.0.33.jar, ecj-4.5.jar, ehcache-2.10.2.2.21.jar, HikariCP-2.4.7.jar, emdq-1.0.jar, sqljdbc4-4.0.jar, ghs-verifyaq-client-1.0.3.jar, mockito-all-1.9.5.jar, junit-4.11.jar, hamcrest-core-1.3.jar, jbehave-core-4.0.4.jar, hamcrest-library-1.3.jar, hamcrest-integration-1.3.jar, commons-collections-3.2.2.jar, plexus-utils-3.0.10.jar, freemarker-2.3.23.jar, paranamer-2.4.jar, jbehave-spring-4.0.4.jar],parent=ClassRealm[plugin>org.jbehave:jbehave-maven-plugin:4.0.4, parent: sun.misc.Launcher$AppClassLoader@55f96302]],embedderControls=UnmodifiableEmbedderControls[EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeouts=300,threads=1,failOnStoryTimeout=false]],embedderFailureStrategy=<null>,configuration=org.jbehave.core.configuration.MostUsefulConfiguration@645b2ac7,candidateSteps=<null>,stepsFactory=<null>,metaFilters=<null>,metaMatchers=<null>,systemProperties={java.awt.headless=true},executorService=<null>,executorServiceCreated=false,performableTree=PerformableTree,storyManager=<null>,timeoutParsers=<null>]
[INFO] Found class names: [com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps]
[INFO] Using controls UnmodifiableEmbedderControls[EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeouts=300,threads=1,failOnStoryTimeout=false]]
[INFO] Running embeddable com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps
[INFO] Processing system properties {java.awt.headless=true}
[INFO] System property 'java.awt.headless' set to 'true'
[INFO] Using controls UnmodifiableEmbedderControls[EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeouts=300,threads=1,failOnStoryTimeout=false]]
[INFO] Generating reports view to 'C:\Users\mylogin\myproject\target\jbehave' using formats '[stats, ide_console, txt, html]' and view properties '{navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, reports=ftl/jbehave-reports.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl, decorated=ftl/jbehave-report-decorated.ftl, maps=ftl/jbehave-maps.ftl}'
[INFO] Reports view generated with 2 stories (of which 1 pending) containing 1 scenarios (of which 1 pending)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.714 s
[INFO] Finished at: 2017-03-28T13:25:28-04:00
[INFO] Final Memory: 38M/299M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.jbehave:jbehave-maven-plugin:4.0.4:run-stories-as-embeddables (run-stories-as-embeddables) on project MyProject: Failed to run stories as embeddables: Failure in running embeddable: com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.jbehave:jbehave-maven-plugin:4.0.4:run-stories-as-embeddables (run-stories-as-embeddables) on project MyProject: Failed to run stories as embeddables
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoFailureException: Failed to run stories as embeddables
at org.jbehave.mojo.RunStoriesAsEmbeddables.execute(RunStoriesAsEmbeddables.java:20)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
... 20 more
Caused by: org.jbehave.core.embedder.Embedder$RunningEmbeddablesFailed: Failure in running embeddable: com.mycompany.myproject.test.behavior.steps.SampleRestCallWithInvalidAccountSteps
at org.jbehave.core.embedder.Embedder.runAsEmbeddables(Embedder.java:140)
at org.jbehave.mojo.RunStoriesAsEmbeddables.execute(RunStoriesAsEmbeddables.java:18)
... 22 more
Caused by: java.lang.NullPointerException
at org.jbehave.core.steps.spring.SpringStepsFactory.stepsTypes(SpringStepsFactory.java:39)
at org.jbehave.core.steps.AbstractStepsFactory.createCandidateSteps(AbstractStepsFactory.java:34)
at org.jbehave.core.embedder.PerformableTree$RunContext.<init>(PerformableTree.java:458)
at org.jbehave.core.embedder.PerformableTree.newRunContext(PerformableTree.java:1105)
at org.jbehave.core.embedder.StoryManager.runStories(StoryManager.java:100)
at org.jbehave.core.embedder.StoryManager.runStoriesAsPaths(StoryManager.java:86)
at org.jbehave.core.embedder.Embedder.runStoriesAsPaths(Embedder.java:213)
at org.jbehave.core.junit.JUnitStory.run(JUnitStory.java:24)
at org.jbehave.core.embedder.Embedder.runAsEmbeddables(Embedder.java:131)
... 23 more
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
我的故事档案,名为sample_rest_call_with_invalid_account_steps.story
:
Scenario: Call the sample rest resource
Given an initial value
When this API is called
Then expect failure
我的java故事类,名为SampleRestCallWithInvalidAccountSteps.java
:
import com.mycompany.myproject.test.behavior.driver.AbstractSpringJBehaveStory;
import com.mycompany.myproject.test.behavior.driver.annotations.BehaviorTest;
import org.jbehave.core.annotations.*;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Scenario: Call the sample rest resource
*/
@RunWith(SpringJUnit4ClassRunner.class)
@BehaviorTest
public class SampleRestCallWithInvalidAccountSteps extends AbstractSpringJBehaveStory {
@Given("an initial value")
public void Given() {
// purposely empty
}
@When("this API is called")
public void When() {
// purposely empty
}
@Then("expect failure")
public void Then() {
// purposely empty
}
}
我的故事超类:
package com.mycompany.myproject.test.behavior.driver;
import java.util.Arrays;
import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.embedder.Embedder;
import org.jbehave.core.embedder.EmbedderControls;
import org.jbehave.core.io.CodeLocations;
import org.jbehave.core.io.LoadFromClasspath;
import org.jbehave.core.io.StoryLoader;
import org.jbehave.core.io.StoryPathResolver;
import org.jbehave.core.io.UnderscoredCamelCaseResolver;
import org.jbehave.core.junit.JUnitStory;
import org.jbehave.core.reporters.FilePrintStreamFactory;
import org.jbehave.core.reporters.Format;
import org.jbehave.core.reporters.StoryReporterBuilder;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.ParameterControls;
import org.jbehave.core.steps.spring.SpringStepsFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
public abstract class AbstractSpringJBehaveStory extends JUnitStory {
@Autowired
private ApplicationContext appContext;
public AbstractSpringJBehaveStory() {
Embedder embedder = new Embedder();
embedder.useEmbedderControls(embedderControls());
embedder.useMetaFilters(Arrays.asList("-skip"));
useEmbedder(embedder);
}
@Override
public InjectableStepsFactory stepsFactory() {
return new SpringStepsFactory(configuration(), appContext);
}
@Override
public Configuration configuration() {
return new MostUsefulConfiguration()
.useStoryPathResolver(storyPathResolver())
.useStoryLoader(storyLoader())
.useStoryReporterBuilder(storyReporterBuilder())
.useParameterControls(parameterControls());
}
private EmbedderControls embedderControls() {
return new EmbedderControls()
.doIgnoreFailureInStories(true)
.doGenerateViewAfterStories(true)
.doVerboseFailures(true);
}
private StoryPathResolver storyPathResolver() {
return new UnderscoredCamelCaseResolver();
}
private StoryLoader storyLoader() {
return new LoadFromClasspath();
}
private StoryReporterBuilder storyReporterBuilder() {
return new StoryReporterBuilder()
.withCodeLocation(CodeLocations.codeLocationFromClass(this.getClass()))
.withPathResolver(new FilePrintStreamFactory.ResolveToPackagedName())
.withFailureTrace(true)
.withDefaultFormats()
.withFormats(Format.IDE_CONSOLE, Format.TXT, Format.HTML);
}
private ParameterControls parameterControls() {
return new ParameterControls()
.useDelimiterNamedParameters(true);
}
}
作为参考,我松散地关注this guide。
答案 0 :(得分:0)
我现在有一个有效的解决方案。我相信我已经缩小了罪魁祸首,在AbstractSpringJBehaveStory
班级中不正当地延长SampleRestCallSteps
。我通过创建一个新的空类来作为AbstractSpringJBehaveStory
的可实例化子类并从extends
中删除SampleRestCallSteps
来修复此问题。
另外,我在创建配置时确实找到了一些缺失的行,我认为这是真正的原因。我从下面的方法中看到了新的,用maven生成一个空白的新JBehave-Spring原型。
@Override
public Configuration configuration() {
ParameterConverters parameterConverters = new ParameterConverters();
ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(
new LocalizedKeywords(),
new LoadFromClasspath(this.getClass()),
parameterConverters);
parameterConverters.addConverters(
new DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
new ExamplesTableConverter(examplesTableFactory));
return new MostUsefulConfiguration()
.useStoryLoader(storyLoader())
.useStoryParser(new RegexStoryParser(examplesTableFactory))
.useStoryReporterBuilder(storyReporterBuilder())
.useStoryPathResolver(storyPathResolver())
.useParameterControls(parameterControls())
.useParameterConverters(parameterConverters);
}
最后,我认为Spring上下文没有正确自动装配,所以我更改了stepsFactory()
这样的方法(再次从maven模板中复制):
@Override
public InjectableStepsFactory stepsFactory() {
ApplicationContext appContext = new SpringApplicationContextFactory("jbehave-app-context.xml")
.createApplicationContext();
return new SpringStepsFactory(configuration(), appContext);
}