Category: I Made This

Improved matching error messages in Extended-Mockito

I’ve recently made some improvements to Extended-Mockito in the area of failure messages.

In early versions, messages from a failure to match in a verify() call were a bit cryptic, especially when matching based on lambdas.  This is what you used to get :

Wanted but not invoked:
exampleService.doAThingWithSomeParameters(
    <Extended matchers$$ lambda$ 6/ 1 5 0 2 6 8 5 4 0>,
    <Extended matchers$$ lambda$ 8/ 3 6 1 5 7 1 9 6 8>,
    <custom argument matcher>,
    <Extended matchers$$ lambda$ 1 1/ 2 1 0 5 0 6 4 1 2>
);

In the first of my examples with the new improvements (available starting in version 2.0.78-beta.1 of extended-mockito and transitively in version 0.9.0 of tdd-mixins-core and tdd-mixins-junit4 ) it’s now possible to show more clearly what kind of arguments were expected:

Wanted but not invoked:
exampleService.doAThingWithSomeParameters(
{String containing all of: [Butcher,Baker,Candlestick Maker]},
[All items matching the given Predicate],
[One or more items matching the given Predicate],
SomeBean where val1 > 5
);

For info, the expectation call which gives this failure message is:

verify(expecting).doAThingWithSomeParameters(this.containsAllOf("Butcher", "Baker", "Candlestick Maker"),
				allSetItemsMatch(s -> s.startsWith("A")),
				oneOrMoreListItemsMatch(s -> s.startsWith("B")),
				objectMatches((SomeBean o) -> o.getVal1() > 5, "SomeBean where val1 > 5"));

Are you sure you’ve sanitized your inputs?

This boggles the mind. Using an alphabet of just 6 non-alphanumeric characters, anyone can write any javascript code. The problem of how to allow some friendly javascript code while blocking anything unfriendly might be a subject worthy of computer science research.

In the meantime, eBay (and others) really should do something to reduce this vulnerability. I have a quick-and-dirty solution in Java based on detecting significantly long runs of the 6 characters in question. The weakness of the attack in question is of course that you need a lot of characters to do anything evil in the obfuscated javascript, so there should be long runs containing only  the 6 characters. It’s possible to include spaces and line breaks and even comments to break up the runs – I took this into account in my solution.  I chose 10 as the run length threshold for detecting the obfuscation, because I don’t know of something legitimate you can do in javascript using 10 of these characters in a row that you couldn’t do another way using some alphabetic characters, and if I saw code with 10 of those characters in a row, I would suspect it right away.

Here’s some of the code in my solution. First, the implementation of containsSneakyJavascript:

public static boolean containsSneakyJavascriptCode(final String userInput) {
	SneakyJSDetectionContext ctx = new SneakyJSDetectionContext(userInput);
	while (ctx.notDone()) {
		ctx.processCurrentChar();
		ctx.nextChar();
	}
	return ctx.detectedSneakyJS();
}

That’s code at a pretty high level of abstraction, so here’s more detail with the implementation of the processCurrentChar() call that you see in the code above. It ignores whitespace and characters inside comments and otherwise checks whether the current character adds to or ends the current run of suspect characters and whether it starts a comment:

void processCurrentChar() {
	if (insideAComment()) {
		checkForEndOfComment();
	} else if (isNotWhiteSpace()) {
		if (isInSneakyAlphabet(currentChar())) {
			incrementCurrentRunLength();
		} else {
			if (isStartOfComment()) {
				setCommentStart();
			} else {
				resetCurrentRunToEmpty();
			}
		}
	}
}

The full implementation code is here, and for good measure here are the unit tests for it.

You’re welcome, eBay.

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).

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.