Published on

Testing Functional Code in Java

Authors

Alright, my brave Java aficionados, time to put on your lab coats and safety glasses, because we're about to dive into the world of testing! No, not the kind where you nervously scribble answers on a piece of paper while guzzling down energy drinks. We're talking about something way more fun (yes, really!) - testing functional code in Java!

Functional code, with its passion for immutability and its "don't touch my stuff!" approach to data, is a hoot to test. Why? Well, because it's predictable. It's like that friend who always orders the same dish at every restaurant - you can count on them, no surprises there!

But how do you test the functional code in Java? Well, you can use the old reliable buddy - JUnit, along with the sharp-dressed and fluent pal - AssertJ.

JUnit is like a Swiss Army knife for testing in Java - it's got you covered.

AssertJ, on the other hand, is like the stylish best friend who always knows how to express things right. It lets you write fluent assertions that are easy to read and understand.

Let's look at a quick example. We have a function that takes in a list of numbers and returns the sum.

public int sum(List<Integer> numbers) {
    return numbers.stream().reduce(0, Integer::sum);
}

With JUnit and AssertJ, we can test this function like so:

@Test
public void testSum() {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    int result = sum(numbers);
    assertThat(result).isEqualTo(15);
}

In this test, assertThat(result).isEqualTo(15) is more expressive than saying assertEquals(15, result). It reads like a sentence: Assert that result is equal to 15.

Alright, but what about property-based testing? Now, that's like bringing a metal detector to a treasure hunt! Instead of testing individual cases, you're testing the characteristics or properties of your function across a wide range of inputs.

Let's say you have a function that checks if a number is even:

public boolean isEven(int number) {
    return number % 2 == 0;
}

A property of this function could be: For any two even numbers, their sum is always even. You can test this property using a library like JUnit-Quickcheck:

@Property(trials = 100)
public void sumOfTwoEvensIsEven(@InRange(minInt = -1000, maxInt = 1000) int a, 
                                 @InRange(minInt = -1000, maxInt = 1000) int b) {
    Assume.assumeTrue(isEven(a) && isEven(b));
    assertTrue(isEven(a + b));
}

In this test, JUnit-Quickcheck will generate pairs of numbers (a, b) 100 times within the range -1000 to 1000. For any pair where both numbers are even, it tests that the sum is also even.

And with that, my friends, we've unraveled the mysterious world of testing functional code in Java. Remember, testing is like flossing. It might seem like a drag, but it keeps everything running smoothly and saves you a ton of pain in the long run. So, test on, you toothy grin flaunting, clean code writing warriors!