Search code examples
javaunit-testingintegration-testingbdd

Is there BDD java framework capable of reusing Given, Then? (with varying When step )


I am looking for BDD java framework with possibility to reuse Given & Then for Unit and Integration tests.

In other words 1. Given some precondition. 2. When - depending on the environment 3. Then verify results of When

I want to be able by changing When, and keeping Given and Then intact, change the type of the test, for example in simple REST service:

  1. UNIT test
    • Given
      • generates some POJO object
    • When
      • receives POJO from Given
      • calls internal service with this POJO
      • receives result in POJO form from the service
      • forwards received POJO to Then
    • Then
      • verifies POJO from When
  2. INTEGRATION test
    • Given
      • generates some POJO object
    • When
      • receives POJO from Given
      • encrypts POJO in external service format
      • calls external service
      • receives result in external service format from exposed service
      • transforms received result in POJO
      • forwards received POJO to Then
    • Then
      • verifies POJO from When

So in example, Given and Then behave the same way, for both integration and unit tests, and by simply changin When the scope of the test goes from UNIT to INTEGRATION.

Can someone point me in the right direction?

I don't want to reinvent the wheel


Solution

  • If you're using Java 8 then you should have a look at this github project.

    Using this you could achieve what you want without the hassle of creating classes. This is due to the use of Generics + Java 8 Lambdas.

    Here are some basic test samples:

    @Test
    public void basicFlowTest() {
     given(1)
      .when("multiplying by 2", givenValue -> 2 * givenValue)
      .then("value should be even", whenValue -> whenValue % 2 == 0);
    }
    
    public void multiTypeFlowTest() {
     LocalDateTime localDateTime = LocalDateTime.now();
     DayOfWeek expectedDay = localDateTime.getDayOfWeek();
    
     given(localDateTime)
      .when("retrieving current day", date -> date.getDayOfWeek())
      .then("days should match", day -> expectedDay == day);
    }
    
    @Test
    public void assertFlowTest() {
     Integer primeNumber = 17;
     given("a prime number", primeNumber)
      .when("finding dividers naively", number -> IntStream.rangeClosed(1, number)
       .boxed().filter(value -> number % value == 0).collect(Collectors.toList()))
      .then(dividers -> {
       assertEquals("should have two dividers", 2, dividers.size());
       assertEquals("first divider should be 1", 1, (int) dividers.get(0));
       assertEquals(String.format("first divider should be %d", primeNumber), primeNumber, dividers.get(1));
      });
    }