Tag: java-8

A Testing Toolbox for Java 8

A few months ago, I presented interface-it, a java-8 tool to generate mixin interfaces. In case you don’t know what that means or why mixins could be useful to you, I wrote a short article which explains it.

One of the key motivations for the interface-it tool was to be able to generate mixins for the latest versions of unit-testing libraries like Mockito and AssertJ. Now you no longer have to worry about that, because I’m doing it for you. And more.

I now have several more projects to present to you.

Presenting tdd-mixins-junit4

Working backwards – if you want to have a great test fixture by adding only one dependency in your build configuration (your Maven Pom, Ivy xml, Gradle, or just a fat jar added to your classpath), use tdd-mixins-junit4. It gives you all the basics you need to do mocking and assertions with fluidity, simplicity and power.

Normally, that’s all you should need for your tests. Mockito allows you to to set up collaborating objects and verify behavior, and the extensions I added make it even easier to handle cases where, for example, you want to mock behavior based on arguments passed to the mock which are generated by your unit under test. As for verifying returned results, AssertJ and JUnit assertions allow you to verify any data returned by the unit under test.

Presenting tdd-mixins-core

If you do not want to use JUnit 4 (maybe you want to use TestNG or an early version of JUnit 5), then you can use tdd-mixins-core, which has everything that tdd-mixins-junit4 has, except the mixin for JUnit assertions and JUnit itself.

Presenting extended-mockito

So these tdd-mixins libraries notably give you mixins for the aforementioned libraries Mockito and AssertJ. As for Mockito, they use my extended-mockito (TODO: link to project) library, which not only provides mixins for classes like Mockito and BDDMockito, but it also provides extra matcher methods to simplify specifying matching arguments for mocked methods. For example:

when(myMockSpamFilter.isSpam(containsOneOrMoreOf("Viagra", "Cialis", "Payday loan")))
            .thenReturn(Boolean.TRUE);

See the project’s home page or the unit tests for more details.

Presenting template-example

As for AssertJ, it’s already quite extended for general purpose use, so there is no extended-assertj project, but if you want to take things farther, I did create a project called template-example, which shows how, with a little tweaking, you can use a Maven plugin to auto-generate custom assertions for your own JavaBeans which are combined with the AssertJ mixin from tdd-mixins-core. These custom assertions allow you to do smooth, fluent assertions for your own data types, allowing this sort of validation call:

assertThat(employee).employer().address().postalCode().startsWith("11");

With these tools, you can more productively write unit tests with powerful assertions and mocking. They give you a fixture that you can set up in any test class by implementing an interface or two – for example:

public class MyTest implements ExtendedMockito, AllAssertions {

Not Included

What’s missing from these tools? I wanted to keep the toolset light, so there are some excellent but more specialized tools which are not included. For example, I have generated a mixin for Jsoup, which is very useful if you need to validate generated HTML, but unless I hear a clamoring for it, I will leave it out of tdd-mixins-core because it adds a dependency that lots of people may not need. Same for extensions to AssertJ – I generated mixins for AssertJ-DB  and for AssertJGuava (UPDATE: also added one for Awaitility), but did not include them in tdd-mixins (you can copy and paste the generated mixins’ source files if you want to use them).

Another library which is useful but which does not lend itself to mixins (because it uses annotations rather than static calls) is Zohhak it simplifies testing methods which return results that depend on a wide variety of possible input values (such as mathematical calculations or business rules).

The What and Why of Mixins in Java 8

A mixin is a type which can be mixed in to (i.e. included in) other types via multiple inheritance. This allows the encapsulation of certain behaviors which cut across the main type hierarchy. In C++ this is fairly standard, though it’s sometimes discouraged because of the potential for the “diamond problem”. In Java 8, mixins can be created using interfaces with default methods.

Why use mixins in Java?

Mixins give you design options which you did not have before. A class can inherit behavior that isn’t in its superclass. For example, you can have Goose implements Honker and Car implements Honker – with no need to implement honk() more than once. Some more practical uses include test fixtures (which I will address in more detail in my next article), and logging.

Default methods in mixins are also very useful for wrapping static method calls, especially in legacy code. This is what my interface-it tool automates. So you can replace static calls with calls to interface methods that can be mocked in tests, and/or overridden for special cases. It allows you to make a procedural design more object-oriented and pull hidden dependencies out into the open. It also lets you avoid using static imports, which can make the code less readable.

Finally, a benefit of mixins is polymorphism.  You can override or extend the default behavior in special cases, which is something you can’t do with static calls.

Presenting interface-it

I’m proud to introduce to you a new tool I created. It’s called interface-it, and it’s an open source project hosted on Github designed to help Java developers to create better test fixtures and to refactor procedural code more easily. More specifically, it’s designed to replace the use of static imports by the use of “mixin” interfaces.

What’s a “mixin”?

A mixin is basically a special kind of class which allows multiple inheritance without potential for unresolvable ambiguity or cycles in the inheritance hierarchy. It provides not just inheritance of the type but also of the implementation. Another word for “mixin”, used in the Scala language, is “trait”.

Before version 8, Java did not allow mixins, but now in Java 8 you can create an interface with default method implementations. Oracle does not especially encourage the use of default method implementations in interfaces – it’s a feature which was added in order to retrofit existing API’s with lambdas (as explained here). However, default methods can be quite useful in certain specific cases.

What’s wrong with static imports?

The site javapractices.com encourages us to “use static imports rarely” because they can make the code more difficult to understand. I’ve even worked in a team which had IDE settings to forbid the use of static imports. When you read code, it’s nice to know whether a method call is defined in the calling class or in another class, and whether it’s a static method or non-static. Static imports hide this information.

Use cases for interface-it

  • Test fixtures

There are tools like Mockito and AssertJ which encourage the use of many static calls in unit test code. You can either use static imports for these and hope your IDE’s auto-completion is up to the task of dealing with them. Or you can wrap the classes with these static methods using interface-it to create mixins used by your test class. In that case, you have no need for a static import (instead you have “class MyTestClass implements Mockito, AssertJ”), and you call methods of these tests tools as though they belong to your test class, because they do belong to it.

Before Java 8, to build a complex test fixture, you needed to create a superclass with all the functionality you might need in your tests, or a hierarchy of fixture classes with added layers of functionality in each subclass. In Java 8 you can use mixins to separate out different functionalities needed for different types of tests, and you can pick and choose which ones each test class needs to implement. Maybe some tests need to implement AssertJ but not Mockito, for example.

The interface-it tool can be used to create mixins for test fixture classes. You can also just copy and paste the example source code for Mockito and/or AssertJ generated by interface-it.

For interface-it’s own test fixtures, I’ve been “eating my own dog food”, so you can see an example of this in the DelegateMethodGeneratorTest class, which “implements AssertJ, Mockito, JUnitAssert” (note that I had to resolve a name conflict between AssertJ and JUnit – the method fail() –  by overriding one of the mixin methods – not a big deal in this case, but I also could have chosen to rename one of the fail() methods in the mixin source code if I had needed to call both methods).

  • Refactoring procedural legacy code

Static methods are not object-oriented. A static call enforces tight coupling, which constrains your design. You can replace an object by another object without modifying the code that uses the object, but a static call links one class to another which can not be replaced (note that some tools like Powermock can use some class loading voodoo to allow you to replace a static call in a test, but that does not fix the inherent design flaw).

In test fixtures, some procedural code is okay, because the tests are generally not reusable objects. Common functionality of different tests can be factored up, but unit tests are largely procedural in nature : setup (“given”), followed by invocation of the unit under test (“when”), followed by validation of results and post-conditions (“then”).

In production code, it’s better to avoid procedural code apart from some factory functionality (where you construct the graph of objects). There’s a lot of legacy production code in the world where a static method is called many times in many different classes. In this case, it’s quite painful to get rid of all these calls at once. Following the Boy Scout Rule, if you need to add one of these calls in the code that you’re working on, or if you are refactoring a class which makes procedural static calls, consider using interface-it to create a mixin which you can use to replace the static call in one place at a time. It’s also useful if you need to write a unit test before doing a more complete refactoring, because the mixin can be mocked in a test. In production code, you don’t necessarily have to have your legacy class implement the mixin as in the test fixture use case. You can simply treat the mixin as the interface of a collaborating object and pass it into the constructor or into specific methods where it’s needed. Where you need to instantiate it in production code, you can create an anonymous subclass, as in “new MyMixin() {}”.

Example usage in refactoring of legacy code:

Imagine we have a supply system which makes online credit card purchases automatically, and the call which does this is a static procedural call.  We want to add flexibility to the design and add unit tests so we can more easily manage code quality and refactorings, but we have these unavoidable static calls everywhere.  We have to start somewhere, so let’s fix SupplyMonitor‘s trackAndProcurePencils() method which checks the inventory of pencils against the number of employees and buys new pencils accordingly:

public void trackAndProcurePencils() {
    int targetPencilCount = this.currentEmployeeCount * TARGET_PENCILS_PER_EMPLOYEE;
    int currentPencilCount = inventory.getItemCount(PENCIL_ITEM_CODE);
    if (currentPencilCount < targetPencilCount) {
        SupplySystem.buy(new PurchaseOrder(PENCIL_ITEM_CODE, targetPencilCount -                  
            currentPencilCount), new CreditCard(CREDIT_CARD_NUMBER));
    }
}

So let’s write a unit test:

@Test
public void should_order_pencils_when_undersupplied() {
    Mockito.when(inventory.getItemCount(SupplyMonitor.PENCIL_ITEM_CODE)).thenReturn(120);
    underTest.trackAndProcurePencils();
    // Oh, dear. Not only to I have no way to test what happened inside the
    // method under test, but I think I just bought 280 pencils with my credit card!!!!
}

Better not commit that – it could get expensive.

We’re going to fix this by generating a wrapper interface which delegates to SupplySystem. In a Windows command-line we type:

C:\dev\eclipsews>java -cp SupplyProject\bin;interface-it\target\interface-it-0.7.0.jar org.interfaceit.ui.commandline.CommandLineMain -n SupplySystemWrapper -c org.legacy.SupplySystem -p org.legacy -d Katas\src\org\legacy -s SupplyProject\src\org\legacy\SupplySystem.java

…and see:

Wrote file: C:\dev\eclipsews\SupplyProject\src\org\legacy\SupplySystemWrapper.java

Now we have our generated wrapper interface. We update the test to look like this:

@Test
public void should_order_pencils_when_undersupplied() {
    Mockito.when(inventory.getItemCount(SupplyMonitor.PENCIL_ITEM_CODE)).thenReturn(120);
    underTest.trackAndProcurePencils();
    Mockito.verify(supplySystem).buy(Mockito.argThat(orderMatcher ), Mockito.any());
}

Note that we could also use interface-it to get rid of the “Mockito.” references in the test code (as previously demonstrated), but it’s better to focus one issue at a time.

Here are links to more complete code for the examples: before refactoring and after refactoring. The generated wrapper interface code can be found here.

Conclusion:

So that’s what interface-it can do for now.  I’ve already started work on improving usability by creating a custom Ant task that manages the generation and update of wrapper interfaces.  Since the jar is available on the Central Repository, anyone with Maven, Gradle or Ivy can easily pull the jar to create their own custom usability solution. If you’re looking for a project, you could use the interface-it jar to create a plugin for your favorite IDE (please leave a comment if you plan to do something like that). You can code whatever UI you want using the ClassCodeGenerator API, specifically by using an instance of DelegateMethodGenerator.

Fear of Streams

There’s an article in the new issue of the French magazine Programmez which got my attention. It chronicles the efforts of some programmers for a B2C site to investigate converting their old for loops into more readable and maintainable Java-8 streams. The article is kind of a mess, actually, but to a software craftsman or craftswoman who works on Java legacy code, the message is a bit frightening.  The programmers did performance tests of the methods they changed, but because some of the more complex methods they modified took twice as long to execute as they did before, their employer was not convinced and does not want them to proceed with a refactor.

If you thought that it was difficult to sell your product owner on the idea of adding days to the schedule to clean up legacy code, imagine having to reveal that the clean-up also involves the risk of performance issues!

Not all of their changes slowed down execution – some even speeded it up a bit.  What troubled me about the article, though, is that I could not predict, looking at the examples they gave of their modifications, which ones would run faster and which ones would run slower than before.

I turned to StackOverflow to see if somebody knows how to do that in general. Is there any way, in a code review, for example, to see if a stream will run significantly slower (a constant-order slowdown, but enough to annoy a user or kill a refactoring initiative) based on just looking at the code?  Of course, it’s possible to code stupidly in a way that will obviously cause a slowdown.  But, apart from some useful guidance about when to use parallel streams and when not to, the message I got from some smart, informed developers is that you can’t, or else it’s not worth the trouble for what amounts to at worst a constant-order slowdown. Of course you should review code changes to make sure they don’t affect the correctness or the complexity of the algorithm, and maybe you can tell whether going parallel would help or hurt performance, but that’s all you can usefully detect.

I think the biggest mistake that the developers in the Programmez article made was to evaluate the performance based on isolated unit tests (microtests).  Performance of a method is not interesting to the end-user.  A  constant-order decrease in performance of a method will frighten a product owner, but maybe the end-user won’t even notice it.  For example, it may be that doubling the execution time of a loop results in a 0.001% decrease in performance of a web request because it’s a loop to process results of a heavy database query.

If the code you work on is for a financial trading application where every nanosecond counts, then you’re not going to be using Java streams at all – you likely have customized collections that run super-fast with no syntactic frills.  For the rest of us, we need to do automated end-to-end performance tests for the scenarios where performance might be an issue.

If you convert for loops to streams, don’t convert everything on the same day. Space out these kinds of changes enough that end-to-end tests will catch only one performance issue at a time.  Then you can reassure the product owner that there will be no “noticeable” decrease in performance from the refactor, but that the code will be more readable and understandable, and thus easier to change and less bug-prone.  For certain iterations which can be parallelized efficiently, there may even be noticeable performance gains.