I'm trying to set up environment such that I can configure an object via method calls, then run tests against it using HTTP requests, thus (semi-pseudocode):
myStore.addCustomer("Jim")
HttpResponse response = httpClient.get("http://localHost/customer/Jim")
assertThat(response.status, is(OK))
(or in JBehave)
Given a customer named Jim
When I make an HTTP GET to path "customer/Jim"
Then the response is 200 OK
And I would like to use Spring Boot to implement the web service.
However, my attempt, although it looks clean, doesn't work because the Spring context seen by my test objects is not the same Spring context used by the web service.
My environment is Serenity+JBehave, but I'm hoping that the principles are no different to straight jUnit.
I have:
@RunWith(SerenityRunner.class)
@SpringApplicationConfiguration(classes = Application.class )
@WebAppConfiguration
@IntegrationTest
public class AcceptanceTestSuite extends SerenityStories {
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Autowired
private Store store;
}
... and the application code:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
... and the class for the object I want to share:
@Component
public class Store {
private String id;
private final Logger log = LoggerFactory.getLogger(Store.class);
public Store() {
log.info("Init");
}
public void addCustomer(String id) {
this.id = id;
log.info("Store " + this + " Set id " + id);
}
public String getCustomerId() {
log.info("Store " + this + " Return id " + id);
return id;
}
}
... in my controller:
@RestController
public class LogNetController {
@Autowired Store store;
@RequestMapping("/customer/{name}")
public String read(name) {
return ...;
}
}
... and in my Serenity step class:
@ContextConfiguration(classes = Application.class)
public class TestSteps extends ScenarioSteps {
@Autowired Store store;
@Step
public void addCustomer(String id) {
store.addCustomer(id);
}
}
When I run my tests, the server starts up, the setter runs, an HTTP request is made. However
- I can see "Init" logged twice by the
Store
constructor: one is created by a Spring context associated with the test, another with a Spring context belonging to the Tomcat container. - and I can see that
Set
andReturn
are logged by different instances ofStore
. Hence I don'tget
the value Iset
.
How can I get the server and the test to see the same Spring context?