Skip to content

Commit 18abf3c

Browse files
author
Lars Bilger
committed
InjectionProviders found in steps classes are now available for injection in all other steps classes, not only the ones that are created after the one the injection provider is defined in.
1 parent b355176 commit 18abf3c

File tree

3 files changed

+87
-20
lines changed

3 files changed

+87
-20
lines changed

needle/src/main/java/cucumber/runtime/java/needle/NeedleFactory.java

+17-11
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,21 @@ public <T> T getInstance(final Class<T> type) {
3939
@Override
4040
public void start() {
4141
logger.trace("start()");
42-
for (final Class<?> stepDefinitionType : cachedStepsInstances.keySet()) {
43-
cachedStepsInstances.put(stepDefinitionType, createStepsInstance(stepDefinitionType));
42+
try {
43+
// First create all instances
44+
for (final Class<?> stepDefinitionType : cachedStepsInstances.keySet()) {
45+
cachedStepsInstances.put(stepDefinitionType, createStepsInstance(stepDefinitionType));
46+
}
47+
// Then collect injection providers from all instances
48+
for (Object stepsInstance : cachedStepsInstances.values()) {
49+
addInjectionProvider(collectInjectionProvidersFromStepsInstance.apply(stepsInstance));
50+
}
51+
// Now init all instances, having the injection providers from all other instances available
52+
for (Object stepsInstance : cachedStepsInstances.values()) {
53+
initTestcase(stepsInstance);
54+
}
55+
} catch (final Exception e) {
56+
throw new IllegalStateException(e);
4457
}
4558
}
4659

@@ -78,16 +91,9 @@ private <T> T nullSafeGetInstance(final Class<T> type) {
7891
return (T) instance;
7992
}
8093

81-
private <T> T createStepsInstance(final Class<T> type) {
94+
private <T> T createStepsInstance(final Class<T> type) throws Exception {
8295
logger.trace("createInstance(): " + type.getCanonicalName());
83-
try {
84-
final T stepsInstance = createInstanceByDefaultConstructor.apply(type);
85-
addInjectionProvider(collectInjectionProvidersFromStepsInstance.apply(stepsInstance));
86-
initTestcase(stepsInstance);
87-
return stepsInstance;
88-
} catch (final Exception e) {
89-
throw new IllegalStateException(e);
90-
}
96+
return createInstanceByDefaultConstructor.apply(type);
9197
}
9298

9399
static InjectionProvider<?>[] setUpInjectionProviders(final String resourceName) {

needle/src/test/java/cucumber/runtime/java/needle/test/AtmWithdrawalSteps.java

+32-9
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
package cucumber.runtime.java.needle.test;
22

3-
import static org.hamcrest.CoreMatchers.is;
4-
import static org.junit.Assert.assertNotNull;
5-
import static org.junit.Assert.assertThat;
6-
import static org.mockito.Mockito.when;
7-
8-
import javax.inject.Inject;
9-
10-
import org.hamcrest.core.Is;
11-
3+
import cucumber.api.java.Before;
124
import cucumber.api.java.en.Given;
135
import cucumber.api.java.en.Then;
146
import cucumber.api.java.en.When;
7+
import cucumber.api.needle.InjectionProviderInstancesSupplier;
158
import cucumber.api.needle.NeedleInjectionProvider;
9+
import cucumber.runtime.java.needle.injection.DefaultInstanceInjectionProvider;
1610
import cucumber.runtime.java.needle.test.atm.AtmService;
1711
import cucumber.runtime.java.needle.test.atm.AtmServiceBean;
1812
import cucumber.runtime.java.needle.test.atm.BicGetter;
1913
import cucumber.runtime.java.needle.test.injectionprovider.ValueInjectionProvider;
2014
import de.akquinet.jbosscc.needle.annotation.ObjectUnderTest;
2115
import de.akquinet.jbosscc.needle.injection.InjectionProvider;
16+
import org.hamcrest.core.Is;
17+
18+
import javax.inject.Inject;
19+
20+
import java.util.Collections;
21+
import java.util.Set;
22+
23+
import static org.hamcrest.CoreMatchers.is;
24+
import static org.junit.Assert.*;
25+
import static org.mockito.Mockito.when;
2226

2327
public class AtmWithdrawalSteps {
2428

@@ -31,12 +35,23 @@ public class AtmWithdrawalSteps {
3135
@Inject
3236
private BicGetter bicGetter;
3337

38+
@Inject
39+
private MoreSteps moreSteps;
40+
3441
/*
3542
* Provider instance will be added dynamically.
3643
*/
3744
@NeedleInjectionProvider
3845
private final InjectionProvider<?> valueProvider = new ValueInjectionProvider(VALUE);
3946

47+
@NeedleInjectionProvider
48+
private final InjectionProviderInstancesSupplier thisInjectionProviderSupplier = new InjectionProviderInstancesSupplier() {
49+
@Override
50+
public Set<InjectionProvider<?>> get() {
51+
return Collections.<InjectionProvider<?>>singleton(new DefaultInstanceInjectionProvider<AtmWithdrawalSteps>(AtmWithdrawalSteps.this));
52+
}
53+
};
54+
4055
/*
4156
* This is what we test
4257
*/
@@ -65,4 +80,12 @@ public void I_have_EUR_remaining(final int remaining) throws Throwable {
6580
assertThat(atmService.getAmount(), Is.is(remaining));
6681
}
6782

83+
@Before
84+
public void checkInjectionWorked() {
85+
assertTrue("Got a mock injected instead of the real instance.", moreSteps.isThisReallyYouOrJustAMock());
86+
}
87+
88+
public boolean isThisReallyYouOrJustAMock() {
89+
return true;
90+
}
6891
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package cucumber.runtime.java.needle.test;
2+
3+
import cucumber.api.java.Before;
4+
import cucumber.api.java.en.Given;
5+
import cucumber.api.needle.NeedleInjectionProvider;
6+
import cucumber.runtime.java.needle.injection.DefaultInstanceInjectionProvider;
7+
import de.akquinet.jbosscc.needle.injection.InjectionProvider;
8+
9+
import javax.inject.Inject;
10+
11+
import static org.junit.Assert.assertTrue;
12+
13+
/**
14+
* Just here to show that injection providers from this class also work in other classes.
15+
*
16+
* @author Lars Bilger
17+
*/
18+
public class MoreSteps {
19+
20+
@NeedleInjectionProvider
21+
private InjectionProvider<MoreSteps> thisInjectionProvider = new DefaultInstanceInjectionProvider<MoreSteps>(this);
22+
23+
@Inject
24+
private AtmWithdrawalSteps atmWithdrawalSteps;
25+
26+
@Before
27+
public void checkInjectionWorked() {
28+
assertTrue("Got a mock injected instead of the real instance.", atmWithdrawalSteps.isThisReallyYouOrJustAMock());
29+
}
30+
31+
@Given("^i call a step that i don't really need$")
32+
public void this_step_is_here_only_to_have_the_class_instantiated() {
33+
}
34+
35+
public boolean isThisReallyYouOrJustAMock() {
36+
return true;
37+
}
38+
}

0 commit comments

Comments
 (0)