@RunWith(SpecRunner.class)
public class ExampleTest extends AcceptanceTest<TestResult> {
private final GivenTheWeatherService theWeatherService = new GivenTheWeatherService(this, testInfrastructure);
private final ThenTheAccessLogLinesContaining theAccessLogLines = new ThenTheAccessLogLinesContaining();
private final ThenAssertion<ThenTheResponse, TestResult> theResponse = ThenTheResponse::new;
private final ThenAssertion<ThenTheResponseHeaders, TestResult> theResponseHeaders = ThenTheResponseHeaders::new;
private final WhenTheWeatherIsRequested theUser = new WhenTheWeatherIsRequested(testInfrastructure, "TheUser");
private final ThenTheWeatherServiceWasCalled theWeatherServiceWasCalled = new ThenTheWeatherServiceWasCalled();
@Test
public void assertionTest() {
given(theWeatherService.willReturn().weatherDescription("light rain").forCity("London"));
when(theUser.requestsTheWeather().forCity("London"));
then(theResponse).isEqualTo("There is light rain in London");
and(theResponseHeaders).contains("Content-Length").contains("Date");
}
@Test
public void assertionBuilderTest() {
given(theWeatherService.willReturn().weatherDescription("light rain").forCity("London"));
when(theUser.requestsTheWeather().forCity("London"));
then(theAccessLogLines.containing("GET /weather")).hasSize(1);
}
@Test
public void verificationTest() {
given(theWeatherService.willReturn().weatherDescription("light rain").forCity("London"));
when(theUser.requestsTheWeather().forCity("London"));
then(theWeatherServiceWasCalled.withCity("London"));
}
}Dependency:
<dependency>
<groupId>io.github.theangrydev.fluentbdd</groupId>
<artifactId>all</artifactId>
<version>8.2.2</version>
</dependency>You can also depend on the modules core, assertj-extensions, hamcrest-extensions, mockito-extensions and yatspec-extensions separately if you don't need all of them.
| Module | Stability | Comments |
|---|---|---|
| core | Stable | Used by a small Agile team on a daily basis since March 2016, contains the bulk of the Fluent BDD framework |
| yatspec-extensions | Stable | Used by a small Agile team on a daily basis since March 2016, lightweight module that pulls in the YatSpec dependency and provides some small integrations |
| assertj-extensions | Experimental | No real world users yet, added since AssertJ has lots of useful assertion methods that could come in handy |
| hamcrest-extensions | Experimental | No real world users yet, added since Hamcrest is a popular framework that users might already be invested in |
| mockito-extensions | Experimental | No real world users yet, developed as a curiosity to see how integration with Mockito could be possible |
The versioning scheme follows Semantic Versioning 2.0.0, to help you identify non backwards-compatible changes when you are upgrading.
- Minor release after some refactoring, no functional changes
- Improving the documentation of the
fluent-mockitomodule
- #11 New module:
hamcrest-extensionsthat acts as a bridge for using Hamcrest matchers asthenassertions
- Added some javadoc to the
allmodule with links to javadoc of the other modules
- #15 Fixed by making
WithFluentAssertJ<TestResult>extendWithFluentBdd<TestResult>and callingrecordThenin eachthenandandmethod. This change is not backwards compatible
- Updated transitive dependency versions
- Marked the transitive dependency
yatspec-zohhak-pluginastestscope notcompilescope
- New module:
assertj-extensionsdelegates to theWithAssertionsAssertJ convenience methods - New module:
assertj-extensions-generator, that produces a plugin that is used to generate the source code forassertj-extensions
- Added an
allconvenience dependency that pulls in all the other modules
- Removed the concept of having a base class, instead encouraging using fields that are exposed via the
With*interfaces - New module:
mockito-extensionsthat integrates with Mockito - New JUnit
@RuleFluentMockitoto use in conjunction withFluentBdd, along withWithFluentMockito
- #8 Renamed the library to fluent-bdd. This change is not backwards compatible
- The
groupIdis nowio.github.theangrydev.fluentbddand theartifactIdiscoreandyatspec-extensions - The packages were changed to reflect this, there is now
io.github.theangrydev.fluentbdd.coreandio.github.theangrydev.fluentbdd.yatspec - The
YatspecFluentclass was renamed toFluentYatspec, similarlyWithYatspecFluentwas renamed toWithFluentYatspec - There is a
FluentBddclass that does not require yatspec at all, with a correspondingWithFluentBddinterface
- #7 The functionality implemented in #6 turned out to be a bit too strict about what it considered to be "mutable". Now the definition of "mutable" is that all the fields must be final. This allows synthetic classes (e.g. a constructor reference) to go through, which turned out to be a common way to write ThenAssertion implementations
- Renamed the base class from
FluentTesttoYatspecFluent. This change is not backwards compatible - Support for using
YatspecFluentas a JUnit@Rulealongside aWithYatspecFluentinterface for the BDD methods if you do not want to extendYatspecFluentas the base class for your tests
- #6 Check if
ThenAssertioninstances have been reused. Also relaxed all the instance checks to classes that appear to be mutable (have at least one instance field)
- Minor changes to the validation messages
- #3 Check that the same
Giveninstance is not used more than once. This is to make it harder to accidentally share state by using the same builder style instance more than once. Similarly forThenVerification
- #5 There are now two kinds of
thenmethods.ThenAssertionis used for chained assertions.ThenVerificationis used for a blob verification that is built up. See theExampleTestfor example usage. This change is not backwards compatible sinceThenwas renamed toThenAssertion
- Made the
FluentTestmethods public. Protected was enough, but it's clearer that they are part of the public API if they are public - Fixed some javadoc language issues
- Removed
InterestingGivensandCapturedInputAndOutputsfields. TheTestStatecan be accessed via the interfaceWithTestStateif it is really needed. This change is not backwards compatible since the fields were visible to subclasses ofFluentTest
- #4 Remove
RequestfromWhen. This change is not backwards compatible - Mark
Givenas a@FunctionalInterfacesince it has a single abstract method
- #1 Relax all the wording validation because it was just getting in the way for users rather than providing any value
- Adapt when to given
- Relax the constrains on when you must use
and. Now you are free to useandandgivenandandandtheninterchangeably, so long as the firstgivenis agivennot anandand the firstthenis athennot anand
- Make it clear that the raw yatspec captured inputs and outputs and interesting givens should not be used
- Allow multiple givens of the same type, even if the given is the same instance (this is useful for e.g. priming a rest endpoint for multiple ids)
- Allow multiple givens of the same type, but not exactly the same one
- Lots of javadoc and renamed
ReadOnlyTestItemstoWriteOnlyTestItems
- Do not allow given given (should be given and)
- Make interesting givens and captured inputs and outputs protected because some yatspec plugins (e.g. sequence diagram generator) need to read them
- Updating yatspec to 1.23
- An alternative approach to givensbuilders etc in yatspec