Introduction
Stubit
Stubit is a collection of extremely simple stubs to replace typical infrastructure dependencies.
To review the code, file issues or suggest changes, please visit the project’s GitHub page.
Getting Started
Requirements
In oder to use Stubit you need a JDK 17 or higher.
Dependencies
To use Stubit in your own project, you need to add it as a dependency to your project.
implementation 'org.stubit:http:0.8.2'
implementation("org.stubit:http:0.8.2")
<dependency>
<groupId>org.stubit</groupId>
<artifactId>http</artifactId>
<version>0.8.2</version>
</dependency>
The http is an example module.
|
Bill of Materials (BOM)
If you want to use more than one module in the same project, you can use Stubit’s bill of materials (BOM) and omit the explicit version for the other modules.
implementation platform('org.stubit:bom:0.8.2')
implementation 'org.stubit:http'
implementation(platform("org.stubit:bom:0.8.2"))
implementation("org.stubit:http")
<project>
<!--…-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.stubit</groupId>
<artifactId>bom</artifactId>
<version>0.8.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- … -->
<dependencies>
<dependency>
<groupId>org.stubit</groupId>
<artifactId>http</artifactId>
</dependency>
</dependencies>
<!-- … -->
</project>
HTTP
The HTTP module contains a simple HTTP server, which can be started locally to stub an HTTP service.
Create and Start the Stub
Instantiating the HttpStub
class automatically starts the stub at a random local port.
try (var httpStub = new HttpStub()) {
String stubAddress = httpStub.address();
assertThat(stubAddress).isNotNull().startsWith("http://localhost:");
}
HttpStub().use { httpStub ->
val stubAddress = httpStub.address()
assertThat(stubAddress).isNotNull().startsWith("http://localhost:")
}
You can get its address via the address
method
String stubAddress = httpStub.address();
val stubAddress = httpStub.address()
Unstubbed Behaviour
By default, the stub will return a 404 response for any path and any method but POST.
var request = new Request.Builder().url(httpStub.address() + "/nothing/here").build();
var response = okHttpClient.newCall(request).execute();
assertThat(response.code()).isEqualTo(404);
assertThat(response.body().string()).isEqualTo("No stubbing for GET /nothing/here");
val request = Request.Builder().url("${httpStub.address()}/nothing/here").build()
val response = okHttpClient.newCall(request).execute()
assertThat(response.code).isEqualTo(404)
assertThat(response.body!!.string()).isEqualTo("No stubbing for GET /nothing/here")
POST Requests
POST requests will by default return a 201 response for any path.
var postRequest =
new Request.Builder()
.url(httpStub.address() + "/nothing/here")
.post(RequestBody.create("Hello".getBytes(StandardCharsets.UTF_8)))
.build();
var postResponse = okHttpClient.newCall(postRequest).execute();
assertThat(postResponse.code()).isEqualTo(201);
assertThat(postResponse.body().string()).isEqualTo("Added stubbing for /nothing/here");
assertThat(postResponse.header("Location")).startsWith("http://localhost");
val postRequest =
Request.Builder()
.url("${httpStub.address()}/nothing/here")
.post("Hello".toRequestBody())
.build()
val postResponse = okHttpClient.newCall(postRequest).execute()
assertThat(postResponse.code).isEqualTo(201)
assertThat(postResponse.body!!.string()).isEqualTo("Added stubbing for /nothing/here")
assertThat(postResponse.header("Location")).startsWith("http://localhost")
The body of the request will be returned for subsequent GET requests.
var request = new Request.Builder().url(postResponse.header("Location")).build();
var response = okHttpClient.newCall(request).execute();
assertThat(response.code()).isEqualTo(200);
assertThat(response.body().string()).isEqualTo("Hello");
val request = Request.Builder().url(postResponse.header("Location")!!).build()
val response = okHttpClient.newCall(request).execute()
assertThat(response.code).isEqualTo(200)
assertThat(response.body!!.string()).isEqualTo("Hello")
This behaviour is likely to change in future releases! |
Stub a Response
You can create a stubbing via the Stubbing.stub()
method
Stubbing stubbing =
Stubbing.stub()
.path("/some/where") (1)
.method("GET") (2)
.returns(StubbedResponse.response().body("Hello").statusCode(200)); (3)
1 | Specifies the path for the stubbing. |
2 | Specifies the method. |
3 | Specifies the response that will be returned. |
val stubbing =
Stubbing.stub()
.path("/some/where") (1)
.method("GET") (2)
.returns(StubbedResponse.response().body("Hello").statusCode(200)) (3)
1 | Specifies the path for the stubbing. |
2 | Specifies the method. |
3 | Specifies the response that will be returned. |
The Stubbing
then needs to be added via the add
method
httpStub.add(stubbing);
httpStub.add(stubbing)
Further requests matching the Stubbing
will now return the StubbedRequest
instead of the default response.
var request = new Request.Builder().url(httpStub.address() + "/some/where").build();
var response = okHttpClient.newCall(request).execute();
assertThat(response.code()).isEqualTo(200);
assertThat(response.body().string()).isEqualTo("Hello");
val request = Request.Builder().url("${httpStub.address()}/some/where").build()
val response = okHttpClient.newCall(request).execute()
assertThat(response.code).isEqualTo(200)
assertThat(response.body!!.string()).isEqualTo("Hello")
Spring Data
The Spring Data module contains stub implementation of the Spring Data repository interfaces, which can be used to replace actual database access in tests.
For instance, if we want to create a test for a service, which injects a CrudRepository, we can simply use a CrudRepositoryStub instead of a real repository.
Create the Stub
Let’s assume we have a service TestService
, which injects a Spring Data CrudRepository
named TestCrudRepository
:
class TestService {
private final TestCrudRepository repository;
@Autowired
public TestService(TestCrudRepository repository) {
this.repository = repository;
}
public List<TestEntity> getAll() {
return stream(repository.findAll().spliterator(), false).toList();
}
public TestEntity getByName(String name) {
return repository.findByName(name).orElseThrow();
}
}
class TestService(
private val repository: TestCrudRepository
) {
fun getAll() = repository.findAll().toList()
fun getByName(name: String) = repository.findByName(name)!!
}
We want to test this service without accessing the database and without specifying its internal behaviour (via a Mock).
TestCrudRepository
is a typical Spring Data repository interface with only one additional method findByName
:
interface TestCrudRepository extends CrudRepository<TestEntity, UUID> {
Optional<TestEntity> findByName(String name);
}
interface TestCrudRepository : CrudRepository<TestEntity, UUID> {
fun findByName(name: String): TestEntity?
}
In oder to create a stub, we need to implement this interface.
By extending from the CrudRepositoryStub
, this only requires to implement the findByName
method:
class TestCrudRepositoryStub extends CrudRepositoryStub<TestEntity, UUID>
implements TestCrudRepository {
@Override
public Optional<TestEntity> findByName(String name) {
return data.values().stream().filter(e -> e.getName().equals(name)).findFirst();
}
}
class TestCrudRepositoryStub : CrudRepositoryStub<TestEntity, UUID>(), TestCrudRepository {
override fun findByName(name: String): TestEntity? {
return data.values.find { e -> e.name.equals(name) }
}
}
Use the Stub
In a test we can now use the TestCrudRepositoryStub
instead of the real repository:
TestCrudRepositoryStub repository = new TestCrudRepositoryStub();
TestService testService = new TestService(repository);
val repository = TestCrudRepositoryStub()
val testService = TestService(repository)
Now we can prepare our test scenario by simply adding entities to the stub. Either one-by-one:
TestEntity savedEntity = repository.save(new TestEntity(randomUUID(), "first entity"));
val savedEntity = repository.save(TestEntity(randomUUID(), "first entity"))
Or multiple at once:
Iterable<TestEntity> savedEntities =
repository.saveAll(
List.of(
new TestEntity(randomUUID(), "second entity"),
new TestEntity(randomUUID(), "third entity")));
val savedEntities =
repository.saveAll(
listOf(
TestEntity(randomUUID(), "second entity"),
TestEntity(randomUUID(), "third entity")))
It is quite handy, that the save methods of a CrudRepository
return the saved entity, so we can easily add the entity to the stub and use the returned entity in our test.
Verify the Stub
After the test, we can verify the stub by checking the entities in the stub:
assertThat(testService.getAll()).contains(savedEntity).containsAll(savedEntities);
assertThat(repository.findByName("first entity")).isPresent().contains(savedEntity);
assertThat(testService.getAll()).contains(savedEntity).containsAll(savedEntities)
assertThat(repository.findByName("first entity")).isNotNull().isEqualTo(savedEntity)
Reusing a Stub
Note that a CrudRepositoryStub
is basically a glorified HashMap
, so we can simply create a new instance for every test.
However, that might require to recreate the service as well.
So, if we want to reuse the stub, we can simply use the deleteAll
method to clear the stub:
repository.deleteAll();
repository.deleteAll()
Random
The Random module contains a collection of builders and utility functions to generate random data.
Random Number
The RandomNumber
class allows to generate random Integer/Long values within a defined min and max range (both inclusive).
For simple integers/longs there are several static methods available.
More complex integers/long can be defined with Builder classes that’s returned by the anInt
/aLong
methods.
- NOTE
-
It is not possible to set max to
Integer.MAX_VALUE
orLong.MAX_VALUE
. The maximum values areInteger.MAX_VALUE - 1
andLong.MAX_VALUE - 1
. This is due to the fact that theSecureRandom.nextInt(int)
andSecureRandom.nextLong(long)
methods are exclusive of the upper bound.
Between Min and Max
int someIntBetween42And4711 = anIntBetween(42, 4711);
assertThat(someIntBetween42And4711).isBetween(42, 4711);
long someLongBetween42And4711 = aLongBetween(42, 4711);
assertThat(someLongBetween42And4711).isBetween(42L, 4711L);
val someIntBetween42And4711 = anIntBetween(42, 4711)
assertThat(someIntBetween42And4711).isBetween(42, 4711)
val someLongBetween42And4711 = aLongBetween(42, 4711)
assertThat(someLongBetween42And4711).isBetween(42L, 4711L)
Positive Integer/Long
int somePositiveInt = aPositiveInt();
assertThat(somePositiveInt).isPositive().isNotZero().isLessThan(Integer.MAX_VALUE);
val somePositiveInt = aPositiveInt()
assertThat(somePositiveInt).isPositive().isNotZero().isLessThan(Integer.MAX_VALUE)
long somePositiveLong = aPositiveLong();
assertThat(somePositiveLong).isPositive().isNotZero().isLessThan(Long.MAX_VALUE);
val somePositiveLong = aPositiveLong()
assertThat(somePositiveLong).isPositive().isNotZero().isLessThan(Long.MAX_VALUE)
Negative Integer/Long
int someNegativeInt = aNegativeInt();
assertThat(someNegativeInt).isNegative().isNotZero().isGreaterThanOrEqualTo(Integer.MIN_VALUE);
val someNegativeInt = aNegativeInt()
assertThat(someNegativeInt).isNegative().isNotZero().isGreaterThanOrEqualTo(Integer.MIN_VALUE)
long someNegativeLong = aNegativeLong();
assertThat(someNegativeLong).isNegative().isNotZero().isGreaterThanOrEqualTo(Long.MIN_VALUE);
val someNegativeLong = aNegativeLong()
assertThat(someNegativeLong).isNegative().isNotZero().isGreaterThanOrEqualTo(Long.MIN_VALUE)
Builder
int someInt = anInt().build();
assertThat(someInt).isBetween(Integer.MIN_VALUE, Integer.MAX_VALUE - 1);
int someIntBetween42And4711 = anInt().min(42).max(4711).build();
assertThat(someIntBetween42And4711).isBetween(42, 4711);
int someIntLessThan4711 = anInt().max(4711).build();
assertThat(someIntLessThan4711).isLessThanOrEqualTo(4711);
int someIntGreaterThanMinus10 = anInt().min(-42).build();
assertThat(someIntGreaterThanMinus10).isGreaterThanOrEqualTo(-42);
val someInt = anInt().build()
assertThat(someInt).isBetween(Integer.MIN_VALUE, Integer.MAX_VALUE - 1)
val someIntBetween42And4711 = anInt().min(42).max(4711).build()
assertThat(someIntBetween42And4711).isBetween(42, 4711)
val someIntLessThan4711 = anInt().max(4711).build()
assertThat(someIntLessThan4711).isLessThanOrEqualTo(4711)
val someIntGreaterThanMinus10 = anInt().min(-42).build()
assertThat(someIntGreaterThanMinus10).isGreaterThanOrEqualTo(-42)
long someLong = aLong().build();
assertThat(someLong).isBetween(Long.MIN_VALUE, Long.MAX_VALUE - 1);
long someLongBetween42And4711 = aLong().min(42L).max(4711L).build();
assertThat(someLongBetween42And4711).isBetween(42L, 4711L);
long someLongLessThan4711 = aLong().max(4711L).build();
assertThat(someLongLessThan4711).isLessThanOrEqualTo(4711L);
long someLongGreaterThanMinus10 = aLong().min(-42L).build();
assertThat(someLongGreaterThanMinus10).isGreaterThanOrEqualTo(-42L);
val someLong = aLong().build()
assertThat(someLong).isBetween(Long.MIN_VALUE, Long.MAX_VALUE - 1)
val someLongBetween42And4711 = aLong().min(42L).max(4711L).build()
assertThat(someLongBetween42And4711).isBetween(42L, 4711L)
val someLongLessThan4711 = aLong().max(4711L).build()
assertThat(someLongLessThan4711).isLessThanOrEqualTo(4711L)
val someLongGreaterThanMinus10 = aLong().min(-42L).build()
assertThat(someLongGreaterThanMinus10).isGreaterThanOrEqualTo(-42L)
Random Choice
The RandomChoice
class allows to make a random choice from the objects in a Collection, an Array, or the values of an Enum type.
For simple selections there are several static chooseAnyFrom
methods available.
More complex selections can be defined with a Builder class that’s returned by the from
method.
From Collection
List<String> choicesList = List.of("a", "b", "c");
String choiceFromList = anyOf(choicesList);
assertThat(choiceFromList).isIn(choicesList);
Map<String, Integer> choicesMap = Map.of("a", 1, "b", 2, "c", 3);
Map.Entry<String, Integer> choiceFromMap = anyOf(choicesMap);
assertThat(choiceFromMap).isIn(choicesMap.entrySet());
val choicesList = List.of("a", "b", "c")
val choiceFromList = anyOf(choicesList)
assertThat(choiceFromList).isIn(choicesList)
val choicesMap = mapOf("a" to 1, "b" to 2, "c" to 3)
val choiceFromMap = anyOf(choicesMap)
assertThat(choiceFromMap).isIn(choicesMap.entries)
From Array
String choiceFromEllipsis = anyOf("a", "b", "c");
assertThat(choiceFromEllipsis).isIn("a", "b", "c");
String[] choiceArray = {"a", "b", "c"};
String choiceFromArray = anyOf(choiceArray[0], choiceArray[1], choiceArray[2]);
assertThat(choiceFromArray).isIn((Object[]) choiceArray);
val choiceFromEllipsis = anyOf("a", "b", "c")
assertThat(choiceFromEllipsis).isIn("a", "b", "c")
val choiceArray = arrayOf("a", "b", "c")
val choiceFromArray = anyOf(choiceArray)
assertThat(choiceFromArray).isIn(choiceArray)
From Enum Type
enum Color {
RED,
GREEN,
BLUE
}
Color choiceFromEnum = any(Color.class);
assertThat(choiceFromEnum).isIn(Color.RED, Color.GREEN, Color.BLUE);
val choiceFromEnum = any(Color::class.java)
assertThat(choiceFromEnum).isIn(Color.RED, Color.GREEN, Color.BLUE)
Builder
String choiceFromEllipsis = aChoiceFrom("a", "b", "c").build();
assertThat(choiceFromEllipsis).isIn("a", "b", "c");
String[] choicesArray = {"a", "b", "c"};
String choiceFromArray = aChoiceFrom(choicesArray).build();
assertThat(choiceFromArray).isIn((Object[]) choicesArray);
var choicesList = List.of("a", "b", "c");
String choiceFromList = aChoiceFrom(choicesList).build();
assertThat(choiceFromList).isIn(choicesList);
Map<String, Integer> choicesMap = Map.of("a", 1, "b", 2, "c", 3);
Map.Entry<String, Integer> choiceFromMap = aChoiceFrom(choicesMap).build();
assertThat(choiceFromMap).isIn(choicesMap.entrySet());
enum Color {
RED,
GREEN,
BLUE
}
Color choiceFromEnum = aChoiceFromValuesOf(Color.class).build();
assertThat(choiceFromEnum).isIn(Color.RED, Color.GREEN, Color.BLUE);
val choiceFromEllipsis = aChoiceFrom("a", "b", "c").build()
assertThat(choiceFromEllipsis).isIn("a", "b", "c")
val choicesArray = arrayOf("a", "b", "c")
val choiceFromArray = aChoiceFrom(choicesArray).build()
assertThat(choiceFromArray).isIn(choicesArray)
val choicesList = listOf("a", "b", "c")
val choiceFromList = aChoiceFrom(choicesList).build()
assertThat(choiceFromList).isIn(choicesList)
val choicesMap = mapOf("a" to 1, "b" to 2, "c" to 3)
val choiceFromMap = aChoiceFrom(choicesMap).build()
assertThat(choiceFromMap).isIn(choicesMap.entries)
val choiceFromEnum = aChoiceFromValuesOf(Color::class.java).build()
assertThat(choiceFromEnum).isIn(Color.RED, Color.GREEN, Color.BLUE)
Additional Choices
String choiceWithAdditions = aChoiceFrom(List.of("a", "b")).and("c", "d").build();
assertThat(choiceWithAdditions).isIn("a", "b", "c", "d");
val choiceWithAdditions = aChoiceFrom("a", "b").and("c", "d").build()
assertThat(choiceWithAdditions).isIn("a", "b", "c", "d")
Excluding Choices
String choiceWithExclusions = aChoiceFrom(List.of("a", "b", "c")).butNot("a").build();
assertThat(choiceWithExclusions).isNotEqualTo("a");
val choiceWithExclusions = aChoiceFrom("a", "b", "c").butNot("a").build()
assertThat(choiceWithExclusions).isNotEqualTo("a")
Random String
The RandomString
class allows to generate random Strings.
E.g. to generate a random German licence plate:
String germanLicensePlate =
aStringStartingWith(lettersFrom(anIntBetween(1, 3), Alphabet.GERMAN).toUpperCase())
.followedBy("-")
.followedBy(latinLetters(2).toUpperCase())
.followedBy(arabicDigits(anIntBetween(1, 4)))
.build();
assertThat(germanLicensePlate).matches("[A-ZÄÖÜẞ]{1,3}-[A-Z]{2}\\d{1,4}");
val germanLicensePlate =
aStringStartingWith(lettersFrom(anIntBetween(1, 3), Alphabet.GERMAN).uppercase())
.followedBy("-")
.followedBy(latinLetters(2).uppercase())
.followedBy(arabicDigits(anIntBetween(1, 4)))
.build()
assertThat(germanLicensePlate).matches("[A-ZÄÖÜẞ]{1,3}-[A-Z]{2}\\d{1,4}")
Or an Iranian licence plate:
String iranianLicensePlate =
aStringStartingWith(digitsFrom(2, DigitSystem.PERSIAN))
.followedBy(aLetterFrom(Alphabet.BASIC_ARABIC))
.followedBy(digitsFrom(3, DigitSystem.PERSIAN))
.build();
assertThat(iranianLicensePlate).matches("[۰-۹]{2}[\\u0600-\\u06FF][۰-۹]{3}");
val iranianLicensePlate =
aStringStartingWith(digitsFrom(2, DigitSystem.PERSIAN))
.followedBy(aLetterFrom(Alphabet.BASIC_ARABIC))
.followedBy(digitsFrom(3, DigitSystem.PERSIAN))
.build()
assertThat(iranianLicensePlate).matches("[۰-۹]{2}[\\u0600-\\u06FF][۰-۹]{3}")
Random Duration
The RandomDuration
class allows to generate random Durations.
Duration someDuration = aDurationBetween(Duration.ZERO, Duration.ofDays(7));
assertThat(someDuration).isBetween(Duration.ZERO, Duration.ofDays(7));
val someDuration = aDurationBetween(Duration.ZERO, Duration.ofDays(7))
assertThat(someDuration).isBetween(Duration.ZERO, Duration.ofDays(7))
Duration someDuration = aDuration().build();
assertThat(someDuration).isBetween(Duration.ZERO, Duration.ofSeconds(Long.MAX_VALUE - 1));
Duration someDurationBetween1And2Hours =
aDuration().min(Duration.ofHours(1)).max(Duration.ofHours(2)).build();
assertThat(someDurationBetween1And2Hours).isBetween(Duration.ofHours(1), Duration.ofHours(2));
Duration someDurationLessThan2Hours = aDuration().max(Duration.ofHours(2)).build();
assertThat(someDurationLessThan2Hours).isLessThanOrEqualTo(Duration.ofHours(2));
Duration someDurationGreaterThan1Hour = aDuration().min(Duration.ofHours(1)).build();
assertThat(someDurationGreaterThan1Hour).isGreaterThanOrEqualTo(Duration.ofHours(1));
val someDuration = aDuration().build()
assertThat(someDuration).isBetween(Duration.ZERO, Duration.ofSeconds(Long.MAX_VALUE - 1))
val someDurationBetween1And2Hours =
aDuration().min(Duration.ofHours(1)).max(Duration.ofHours(2)).build()
assertThat(someDurationBetween1And2Hours).isBetween(Duration.ofHours(1), Duration.ofHours(2))
val someDurationLessThan2Hours = aDuration().max(Duration.ofHours(2)).build()
assertThat(someDurationLessThan2Hours).isLessThanOrEqualTo(Duration.ofHours(2))
val someDurationGreaterThan1Hour = aDuration().min(Duration.ofHours(1)).build()
assertThat(someDurationGreaterThan1Hour).isGreaterThanOrEqualTo(Duration.ofHours(1))
Random Date
The RandomLocalDate
class allows to generate random LocalDates.
LocalDate someLockdownDay =
aLocalDateBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4));
assertThat(someLockdownDay).isBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4));
val someLockdownDay =
aLocalDateBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4))
assertThat(someLockdownDay).isBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4))
LocalDate someLocalDate = aLocalDate().build();
assertThat(someLocalDate).isBetween(LocalDate.MIN, LocalDate.MAX);
LocalDate someDateIn2025 = aLocalDate().year(2025).build();
assertThat(someDateIn2025.getYear()).isEqualTo(2025);
LocalDate someDateInMarch = aLocalDate().month(Month.MARCH).build();
assertThat(someDateInMarch.getMonth()).isEqualTo(Month.MARCH);
LocalDate someDateInMarch2025 = aLocalDate().year(2025).month(Month.MARCH).build();
assertThat(someDateInMarch2025.getYear()).isEqualTo(2025);
assertThat(someDateInMarch2025.getMonth()).isEqualTo(Month.MARCH);
LocalDate some3rd = aLocalDate().dayOfMonth(3).build();
assertThat(some3rd.getDayOfMonth()).isEqualTo(3);
LocalDate someSunday = aLocalDate().dayOfWeek(DayOfWeek.SUNDAY).build();
assertThat(someSunday.getDayOfWeek()).isEqualTo(DayOfWeek.SUNDAY);
LocalDate someTuesday1999 = aLocalDate().year(1999).dayOfWeek(DayOfWeek.TUESDAY).build();
assertThat(someTuesday1999.getDayOfWeek()).isEqualTo(DayOfWeek.TUESDAY);
assertThat(someTuesday1999.getYear()).isEqualTo(1999);
val someLocalDate = aLocalDate().build()
assertThat(someLocalDate).isBetween(LocalDate.MIN, LocalDate.MAX)
val someDateIn2025 = aLocalDate().year(2025).build()
assertThat(someDateIn2025.year).isEqualTo(2025)
val someDateInMarch = aLocalDate().month(Month.MARCH).build()
assertThat(someDateInMarch.month).isEqualTo(Month.MARCH)
val someDateInMarch2025 = aLocalDate().year(2025).month(Month.MARCH).build()
assertThat(someDateInMarch2025.year).isEqualTo(2025)
assertThat(someDateInMarch2025.month).isEqualTo(Month.MARCH)
val some3rd = aLocalDate().dayOfMonth(3).build()
assertThat(some3rd.dayOfMonth).isEqualTo(3)
val someSunday = aLocalDate().dayOfWeek(DayOfWeek.SUNDAY).build()
assertThat(someSunday.dayOfWeek).isEqualTo(DayOfWeek.SUNDAY)
val someTuesday1999 = aLocalDate().year(1999).dayOfWeek(DayOfWeek.TUESDAY).build()
assertThat(someTuesday1999.dayOfWeek).isEqualTo(DayOfWeek.TUESDAY)
assertThat(someTuesday1999.year).isEqualTo(1999)
LocalDate someLocalDate = aLocalDateInRange().build();
assertThat(someLocalDate).isBetween(LocalDate.MIN, LocalDate.MAX);
LocalDate someFutureDay = aLocalDateInRange().future().build();
assertThat(someFutureDay).isAfterOrEqualTo(LocalDate.now());
LocalDate somePastDay = aLocalDateInRange().past().build();
assertThat(somePastDay).isBeforeOrEqualTo(LocalDate.now());
LocalDate somePastAfterChristDay =
aLocalDateInRange().past().after(LocalDate.of(1, 1, 1)).build();
assertThat(somePastAfterChristDay)
.isBeforeOrEqualTo(LocalDate.now())
.isAfterOrEqualTo(LocalDate.of(1, 1, 1));
LocalDate someFutureDayInTheNext5Years =
aLocalDateInRange().future().before(Year.now().plusYears(5).atDay(1)).build();
assertThat(someFutureDayInTheNext5Years)
.isAfterOrEqualTo(LocalDate.now())
.isBeforeOrEqualTo(Year.now().plusYears(5).atDay(1));
LocalDate someLockdownDay =
aLocalDateInRange()
.after(LocalDate.of(2020, 3, 8))
.before(LocalDate.of(2020, 5, 4))
.build();
assertThat(someLockdownDay).isBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4));
val someLocalDate = aLocalDateInRange().build()
assertThat(someLocalDate).isBetween(LocalDate.MIN, LocalDate.MAX)
val someFutureDay = aLocalDateInRange().future().build()
assertThat(someFutureDay).isAfterOrEqualTo(LocalDate.now())
val somePastDay = aLocalDateInRange().past().build()
assertThat(somePastDay).isBeforeOrEqualTo(LocalDate.now())
val somePastAfterChristDay =
aLocalDateInRange().past().after(LocalDate.of(1, 1, 1)).build()
assertThat(somePastAfterChristDay)
.isBeforeOrEqualTo(LocalDate.now())
.isAfterOrEqualTo(LocalDate.of(1, 1, 1))
val someFutureDayInTheNext5Years =
aLocalDateInRange().future().before(Year.now().plusYears(5).atDay(1)).build()
assertThat(someFutureDayInTheNext5Years)
.isAfterOrEqualTo(LocalDate.now())
.isBeforeOrEqualTo(Year.now().plusYears(5).atDay(1))
val someLockdownDay =
aLocalDateInRange()
.after(LocalDate.of(2020, 3, 8))
.before(LocalDate.of(2020, 5, 4))
.build()
assertThat(someLockdownDay).isBetween(LocalDate.of(2020, 3, 8), LocalDate.of(2020, 5, 4))
Random Time
The RandomLocalTime
class allows to generate random LocalTimes.
LocalTime someTimeBusinessHours = aLocalTimeBetween(LocalTime.of(9, 0), LocalTime.of(17, 0, 0));
assertThat(someTimeBusinessHours).isBetween(LocalTime.of(9, 0), LocalTime.of(17, 0));
val someTimeBusinessHours = aLocalTimeBetween(LocalTime.of(9, 0), LocalTime.of(17, 0, 0))
assertThat(someTimeBusinessHours).isBetween(LocalTime.of(9, 0), LocalTime.of(17, 0))
LocalTime someLocalTime = aLocalTime().build();
assertThat(someLocalTime).isBetween(LocalTime.MIN, LocalTime.MAX);
LocalTime someTimeAt12 = aLocalTime().hour(12).build();
assertThat(someTimeAt12.getHour()).isEqualTo(12);
LocalTime someHalfTime = aLocalTime().minute(30).build();
assertThat(someHalfTime.getMinute()).isEqualTo(30);
LocalTime someTimeAlmostFull = aLocalTime().minute(59).second(59).nano(999_999_999).build();
assertThat(someTimeAlmostFull.getMinute()).isEqualTo(59);
assertThat(someTimeAlmostFull.getSecond()).isEqualTo(59);
assertThat(someTimeAlmostFull.getNano()).isEqualTo(999_999_999);
val someLocalTime = aLocalTime().build()
assertThat(someLocalTime).isBetween(LocalTime.MIN, LocalTime.MAX)
val someTimeAt12 = aLocalTime().hour(12).build()
assertThat(someTimeAt12.hour).isEqualTo(12)
val someHalfTime = aLocalTime().minute(30).build()
assertThat(someHalfTime.minute).isEqualTo(30)
val someTimeAlmostFull = aLocalTime().minute(59).second(59).nano(999_999_999).build()
assertThat(someTimeAlmostFull.minute).isEqualTo(59)
assertThat(someTimeAlmostFull.second).isEqualTo(59)
assertThat(someTimeAlmostFull.nano).isEqualTo(999_999_999)
LocalTime someLocalTime = aLocalTimeInRange().build();
assertThat(someLocalTime).isBetween(LocalTime.MIN, LocalTime.MAX);
LocalTime someFutureTime = aLocalTimeInRange().future().build();
assertThat(someFutureTime).isAfterOrEqualTo(LocalTime.now());
LocalTime somePastTime = aLocalTimeInRange().past().build();
assertThat(somePastTime).isBeforeOrEqualTo(LocalTime.now());
LocalTime someTimeAfterNoon = aLocalTimeInRange().after(LocalTime.NOON).build();
assertThat(someTimeAfterNoon).isAfterOrEqualTo(LocalTime.NOON);
val someLocalTime = aLocalTimeInRange().build()
assertThat(someLocalTime).isBetween(LocalTime.MIN, LocalTime.MAX)
val someFutureTime = aLocalTimeInRange().future().build()
assertThat(someFutureTime).isAfterOrEqualTo(LocalTime.now())
val somePastTime = aLocalTimeInRange().past().build()
assertThat(somePastTime).isBeforeOrEqualTo(LocalTime.now())
val someTimeAfterNoon = aLocalTimeInRange().after(LocalTime.NOON).build()
assertThat(someTimeAfterNoon).isAfterOrEqualTo(LocalTime.NOON)