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

[Spring] Document CucumberContextConfiguration semantics #2887

Merged
merged 3 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Fixed
- [Spring] Document `@CucumberContextConfiguration` semantics ([#2887](https://github.com/cucumber/cucumber-jvm/pull/2887) M.P. Korstanje)

## [7.18.0] - 2024-05-17
### Added
Expand Down
76 changes: 75 additions & 1 deletion cucumber-spring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public class CucumberSpringConfiguration {
Note: Cucumber Spring uses Spring's `TestContextManager` framework internally.
As a result, a single Cucumber scenario will mostly behave like a JUnit test.

The class annotated with `@CucumberContextConfiguration` is instantiated but not
initialized by Spring. Instead, this instance is processed by Springs test
execution listeners. So features that depend on a test execution listener such
as mock beans will work on the annotated class - but not on other step definition
classes. Features that depend on initializing beans - such as AspectJ - will not
work on the annotated class - but will work on other step definition classes.

For more information configuring Spring tests see:
- [Spring Framework Documentation - Testing](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html)
- [Spring Boot Features - Testing](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-testing)
Expand Down Expand Up @@ -97,7 +104,8 @@ Repeat as needed.
## Accessing the application context

Components from the application context can be accessed by autowiring.
Annotate a field in your step definition class with `@Autowired`.

Either annotate a field in your step definition class with `@Autowired`

```java
package com.example.app;
Expand All @@ -117,6 +125,72 @@ public class MyStepDefinitions {
}
```

Or declare a dependency through the constructor:

```java
package com.example.app;

import io.cucumber.java.en.Given;

public class MyStepDefinitions {

private final MyService myService;

public MyStepDefinitions(MyService myService){
this.myService = myService;
}

@Given("feed back is requested from my service")
public void feed_back_is_requested(){
myService.requestFeedBack();
}
}
```

## Using Mock Beans

To use mock beans, declare a mock bean in the context configuration.

```java
package com.example.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;

import io.cucumber.spring.CucumberContextConfiguration;

@CucumberContextConfiguration
@SpringBootTest(classes = TestConfig.class)
@MockBean(MyService.class)
public class CucumberSpringConfiguration {

}
```

Then in your step definitions, use the mock as you would normally.

```java
package com.example.app;

import org.springframework.beans.factory.annotation.Autowired;
import io.cucumber.java.en.Given;

import static org.mockito.Mockito.mockingDetails;
import static org.springframework.test.util.AssertionErrors.assertTrue;

public class MyStepDefinitions {

@Autowired
private MyService myService;

@Given("my service is a mock")
public void feed_back_is_requested(){
assertTrue(mockingDetails(myService).isMock());
}
}
```

## Sharing State

Cucumber Spring creates an application context and uses Spring's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* public class CucumberSpringConfiguration {
* }
* </pre>
*
* <p>
* Notes:
* <ul>
* <li>Only one glue class should be annotated with
Expand All @@ -30,6 +30,15 @@
* <li>Cucumber Spring uses Spring's {@code TestContextManager} framework
* internally. As a result a single Cucumber scenario will mostly behave like a
* JUnit test.</li>
* <li>The class annotated with {@code CucumberContextConfiguration} is
* instantiated but not initialized by Spring. This instance is processed by
* Springs {@link org.springframework.test.context.TestExecutionListener
* TestExecutionListeners}. So features that depend on a test execution listener
* such as mock beans will work on the annotated class - but not on other step
* definition classes. Features that depend on initializing beans - such as
* AspectJ - will not work on the annotated class - but will work on other step
* definition classes.</li>
* <li></li>
* </ul>
*/
@Retention(RetentionPolicy.RUNTIME)
Expand Down