Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runner instantiate steps unnecessarily when building JUnit Descriptions #29

Closed
codespelunker opened this issue Mar 22, 2013 · 2 comments
Milestone

Comments

@codespelunker
Copy link

The JUnitReportingRunner instantiates step classes before any scenarios are actually executed as a part of an attempt to build JUnit Descriptions. This can create a problem with Guice integrations (and possibly others).

When Guice is configured to instantiate Step classes as singletons, it doesn't make any difference. But when using Guice custom scopes--for example, scoping a Step to a scenario--this causes the runner to fail, because objects required by the Step don't exist until a scenario exists. The exact error with stack trace is included below.

The problem code is inside JUnitDescriptionGenerator.addRegularStep(), as shown below:

    Description testDescription = Description.createTestDescription(step
            .getStepsInstance().getClass(), getJunitSafeString(stringStep));
    description.addChild(testDescription);

The Description requires the Class only, not an instance of the Class. Is there a way to obtain the Class of the Step without requiring an instance? That would fix this problem. A quick glance at the JBehave StepCandidate class suggest that the Class type is not exposed, but perhaps there is some other way to get it.

A link to a sample project exposing the problem is here: http://bit.ly/11pLRvq (sorry, it's the only way I could find to upload it--GitHub doesn't allow file attachments). Note: you must run it through Eclipse to see the problem. Maven does not see the test class. This problem is specific to the JUnitReportingRunner. Running with the default AnnotatedEmbedderRunner works normally.

Version information is in the pom.xml, and also included below:

jbehave-junit-runner: 1.0.1
jbehave: 3.6.9

Error:

com.google.inject.ProvisionException: Guice provision errors:

  1. Error in custom provider, com.google.inject.OutOfScopeException: Cannot access Key[type=example.ScenarioScopeSteps, annotation=[none]] outside of a scoping block
    at example.AppModule.configure(AppModule.java:12)
    while locating example.ScenarioScopeSteps

1 error
at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:987)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1009)
at org.jbehave.core.steps.guice.GuiceStepsFactory.addInstances(GuiceStepsFactory.java:72)
at org.jbehave.core.steps.guice.GuiceStepsFactory.createInstanceOfType(GuiceStepsFactory.java:61)
at org.jbehave.core.steps.StepCandidate.getStepsInstance(StepCandidate.java:68)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.addRegularStep(JUnitDescriptionGenerator.java:190)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.addExistingStep(JUnitDescriptionGenerator.java:148)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.addSteps(JUnitDescriptionGenerator.java:138)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.addStepsToExample(JUnitDescriptionGenerator.java:127)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.createDescriptionFrom(JUnitDescriptionGenerator.java:57)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.addAllScenariosToDescription(JUnitDescriptionGenerator.java:208)
at de.codecentric.jbehave.junit.monitoring.JUnitDescriptionGenerator.createDescriptionFrom(JUnitDescriptionGenerator.java:44)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.addStories(JUnitReportingRunner.java:194)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.buildDescriptionFromStories(JUnitReportingRunner.java:181)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.(JUnitReportingRunner.java:51)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.google.inject.OutOfScopeException: Cannot access Key[type=example.ScenarioScopeSteps, annotation=[none]] outside of a scoping block
at example.SimpleScope.getScopedObjectMap(SimpleScope.java:97)
at example.SimpleScope.access$0(SimpleScope.java:94)
at example.SimpleScope$2.get(SimpleScope.java:81)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974)
... 32 more

@codespelunker
Copy link
Author

FYI, I'm not sure of an easy way to fix this without changing the StepCandidate class in JBehave. I have logged an issue for that with them: JBEHAVE-895.

@AndreasEK
Copy link
Contributor

Fixed with merging your pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants