Posts Tagged ‘tests’

Mockito-Java8 is a set of Mockito add-ons leveraging Java 8 and lambda expressions to make mocking with Mockito even more compact.

At the beginning of 2015 I gave my flash talk Java 8 brings power to testing! at GeeCON TDD 2015 and DevConf.cz 2015. In my speech using 4 examples I showed how Java 8 – namely lambda expressions – can simplify testing tools and testing in general. One of those tools was Mokcito. To not let my PoC code die on slides and to make it simply available for others I have released a small project with two, useful in specified case, Java 8 add-ons for Mockito.

Mockito logo

Quick introduction

As a prerequisite, let’s assume we have the following data structure:

@Immutable
class ShipSearchCriteria {
    int minimumRange;
    int numberOfPhasers;
}

The library provides two add-ons:

Lambda matcher – allows to define matcher logic within a lambda expression.

given(ts.findNumberOfShipsInRangeByCriteria(
    argLambda(sc -> sc.getMinimumRange() > 1000))).willReturn(4);

Argument Captor – Java 8 edition – allows to use ArgumentCaptor in a one line (here with AssertJ):

verify(ts).findNumberOfShipsInRangeByCriteria(
    assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));

Lambda matcher

With a help of the static method argLambda a lambda matcher instance is created which can be used to define matcher logic within a lambda expression (here for stubbing). It could be especially useful when working with complex classes pass as an argument.

@Test
public void shouldAllowToUseLambdaInStubbing() {
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(
        argLambda(sc -> sc.getMinimumRange() > 1000))).willReturn(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

In comparison the same logic implemented with a custom Answer in Java 7:

@Test
public void stubbingWithCustomAsnwerShouldBeLonger() {  //old way
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(new Answer<Integer>() {
        @Override
        public Integer answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            ShipSearchCriteria criteria = (ShipSearchCriteria) args[0];
            if (criteria.getMinimumRange() > 1000) {
                return 4;
            } else {
                return 0;
            }
        }
    });
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

Even Java 8 and less readable constructions don’t help too much:

@Test
public void stubbingWithCustomAsnwerShouldBeLongerEvenAsLambda() {  //old way
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(invocation -> {
        ShipSearchCriteria criteria = (ShipSearchCriteria) invocation.getArguments()[0];
        return criteria.getMinimumRange() > 1000 ? 4 : 0;
    });
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

Argument Captor – Java 8 edition

A static method assertArg creates an argument matcher which implementation internally uses ArgumentMatcher with an assertion provided in a lambda expression. The example below uses AssertJ to provide meaningful error message, but any assertions (like native from TestNG or JUnit) could be used (if really needed). This allows to have inlined ArgumentCaptor:

@Test
public void shouldAllowToUseAssertionInLambda() {
    //when
    ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
    //then
    verify(ts).findNumberOfShipsInRangeByCriteria(
        assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));
}

In comparison to 3 lines in the classic way:

@Test
public void shouldAllowToUseArgumentCaptorInClassicWay() {  //old way
    //when
    ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
    //then
    ArgumentCaptor<ShipSearchCriteria> captor = 
        ArgumentCaptor.forClass(ShipSearchCriteria.class);
    verify(ts).findNumberOfShipsInRangeByCriteria(captor.capture());
    assertThat(captor.getValue().getMinimumRange()).isLessThan(2000);
}

Summary

The presented add-ons were created as PoC for my conference speech, but should be fully functional and potentially useful in the specific cases. To use it in your project it is enough to use Mockito 1.10.x or 2.0.x-beta, add mockito-java8 as a dependency and of course compile your project with Java 8+.

More details are available on the project webpage: https://github.com/szpak/mockito-java8

Update 20151217. You may be also interested in my new blog post about using Mockito wihtout static imports.

Advertisements

Quick tutorial how to configure Spock 1.0 with Groovy 2.4 using Maven and Gradle.

Spock 1.0 has been finally released. About new features and enhancements I already wrote two blog posts. One of the recent changes was a separation on artifacts designed for specific Groovy versions: 2.0, 2.2, 2.3 and 2.4 to minimize a chance to come across a binary incompatibility in runtime (in the past there were only versions for Groovy 1.8 and 2.0+). That was done suddenly and based on the messages on the mailing list it confused some people. After being twice asked to help properly configure two projects I decided to write a short post presenting how to configure Spock 1.0 with Groovy 2.4 in Maven and Gradle. It is also a great place to compare how much work is required to do it in those two very popular build systems.

Maven

Maven does not natively support other JVM languages (like Groovy or Scala). To use it in the Maven project it is required to use a third party plugin. For Groovy the best option seems to be GMavenPlus (a rewrite of no longer maintained GMaven plugin). An alternative is a plugin which allows to use Groovy-Eclipse compiler with Maven, but it is not using official groovyc and in the past there were problems with being up-to-date with the new releases/features of Groovy.

Sample configuration of GMavenPlus plugin could look like:

<plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>testCompile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

As we want to write tests in Spock which recommends to name files with Spec suffix (from specification) in addition it is required to tell Surefire to look for tests also in those files:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <configuration>
        <includes>
            <include>**/*Spec.java</include> <!-- Yes, .java extension -->
            <include>**/*Test.java</include> <!-- Just in case of having also "normal" JUnit tests -->
        </includes>
    </configuration>
</plugin>

Please notice that it is needed to include **/*Spec.java not **/*Spec.groovy to make it work.

Also dependencies have to be added:

    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.0-groovy-2.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

It is very important to take a proper version of Spock. For Groovy 2.4 version 1.0-groovy-2.4 is required. For Groovy 2.3 version 1.0-groovy-2.3. In case of mistake Spock protests with a clear error message:

Could not instantiate global transform class
org.spockframework.compiler.SpockTransform specified at
jar:file:/home/foo/.../spock-core-1.0-groovy-2.3.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
because of exception
org.spockframework.util.IncompatibleGroovyVersionException:
The Spock compiler plugin cannot execute because Spock 1.0.0-groovy-2.3 is
not compatible with Groovy 2.4.0. For more information, see
http://versioninfo.spockframework.org

Together with other mandatory pom.xml elements the file size increased to over 50 lines of XML. Quite much just for Groovy and Spock. Let’s see how complicated it is in Gradle.

Gradle

Gradle has built-in support for Groovy and Scala. Without further ado Groovy plugin just has to be applied.

apply plugin: 'groovy'

Next the dependencies has to be added:

compile 'org.codehaus.groovy:groovy-all:2.4.1'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'

and the information where Gradle should look for them:

repositories {
    mavenCentral()
}

Together with defining package group and version it took 15 lines of code in Groovy-based DSL.

Btw, in case of Gradle it is also very important to match Spock and Groovy version, e.g. Groovy 2.4.1 and Spock 1.0-groovy-2.4.

Summary

Thanks to embedded support for Groovy and compact DSL Gradle is preferred solution to start playing with Spock (and Groovy in general). Nevertheless if you prefer Apache Maven with a help of GMavenPlus (and XML) it is also possible to build project tested with Spock.

The minimal working project with Spock 1.0 and Groovy 2.4 configured in Maven and Gradle can be cloned from my GitHub.

Graphical comparison of Spock and Groovy configuration in Maven and Gradle

Bonus: Graphical comparison of Spock and Groovy configuration in Maven and Gradle

Note. I haven’t been using Maven in my project for over 2 years (I prefer Gradle), so if there is a better/easier way to configure Groovy and Spock with Maven just let me know in the comments.

Note 2. The configuration examples assume that Groovy is used only for tests and the production code is written in Java. It is possible to mix Groovy and Java code together, but then the configuration is a little more complicated.

Note 3. If you are interested in get know useful tips and tricks about using Spock Framework to test your Java and Groovy code I will have a presentation about that at 4Developers conference, April 20th, 2015.

Update 20150310. Redesigned summary.

Leonard Nimoy 1931-2015

When writing integration tests it is sometimes required to set up environment initial conditions/state before/after a given test or the whole specification. Upcoming Spock 1.0 expands the number of available options to do it in the convenient way.

This is the second part of the series about new and noteworthy in (upcoming) Spock 1.0.

New extension @RestoreSystemProperties

System properties provides information about JVM configuration and the environment like JVM vendor and version, operating system, classpath, locale or a time zone. Some of them can impact the way our application works. The following example checks if the protection before running a dangerous program as root works properly on Unix machines. To not affect other tests @RestoreSystemProperties restores the original system properties.

@Stepwise
class RestoreSystemPropertiesSpec extends Specification {

    @RestoreSystemProperties
    def "should deny perform action when running as root"() {
        given:
            System.setProperty("user.name", "root")
        and:
            def sut = new DangerousActionPerformer()
        when:
            sut.squashThemAll()
        then:
            thrown(IllegalStateException)
    }

    def "should perform action when running as 'normal' user"() {
        given:
            def sut = new DangerousActionPerformer()
        when:
            sut.squashThemAll() //current user name was restored
        then:
            noExceptionThrown()
    }

    (...)
}

The extension can be activated using @RestoreSystemProperties annotation. It can be placed on a feature method to be applied right after the given test only or on a class to restore system properties after every test in the specification. The behavior in the second case is identical to placing the annotation on every test method.

Internally Spock makes a copy of a system Properties structure before a test and restores it after.

@ConfineMetaClassChanges (since 0.7)

One of the things which make Groovy language so powerful is metaprogramming – an ability to modify classes (e.g. add/modify new methods) at runtime. That could look like hacking (and that is true), but in some specific cases it is very useful (see Grails and GORM for creating database queries when non existing methods – like findByFirstNameAndSecondName(...) or writing a custom DSL like 6.minutes.ago).

MetaClass operations are usually executed at the class (not instance) level what generally causes that they affect every class instance in given class loader. GORM like changes done in multiple test could interact each other causing tests to fail. For that cases @ConfineMetaClassChanges extension (available already in previous Spock version) was created.

@Stepwise
class ConfineMetaClassChangesSpec extends Specification {

    @ConfineMetaClassChanges(EmptyClass)
    def "should allow to call added method"() {
        given:
            EmptyClass.metaClass.returnFoo = { "foo" }
        when:
            def fooValue = new EmptyClass().returnFoo()
        then:
            fooValue == "foo"

    }

    def "should throw exception on not available method"() {
        when:
            new EmptyClass().returnFoo()
        then:
            thrown(MissingMethodException)
    }
}

class EmptyClass {
}

@ConfineMetaClassChanges annotation can be placed on a feature method to restore MetaClass to the state just before that test or on a class to restore system properties after the last test in the specification to the state before calling the setupSpec method.

Note that @ConfineMetaClassChanges behavior placed on a specification level is different (once after the last test) than @RestoreSystemProperties behavior (every time after every test).

@AutoCleanup (since 0.7)

Another already existing, but rarely known and used extension is @AutoCleanup. Usually external resources are allocated in setup/setupSpec methods and released in cleanup/cleanupSpec methods. But Spock, the same as pure JUnit, support auto initialization instance variables (fields) before every test/feature (which overrides default Java behavior when a field is initialized only once when a class instance is created).

class ManualCleanupSpec extends Specification {

    @Shared
    private DBConnection dbConnection = new H2DBConnection()

    void cleanupSpec() {
        dbConnection.close()    //boilerplate code
    }

    def "should do fancy thing on DB"() {
        ...
    }
}

interface DBConnection {
    void close()
}

To make it easier to release those inlined resources can be annotated with @AutoCleanup to call close method (or any other method defined as a parameter) in the clean up phase.

class AutoCleanupSpec extends Specification {

    @AutoCleanup
    @Shared
    private DBConnection dbConnection = new H2DBConnection()

    def "should do fancy thing on DB"() {
        ...
    }
}

@AutoCleanup supports both instance variables (the method is called after every tests) and static/@Shared fields (the clean up is performed after the last test). All errors during clean up are caught to not interrupt test execution. By default there are logged, which can be disabled using quiet parameter @AutoCleanup(quiet = true).

Where can I find Spock 1.0?

Please notice that blog post is about features available in Git branch planned to become Spock 1.0 sometime in the future. They are currently available only in a 1.0-SNAPSHOT version in a separate repository. As not being released (at the time of writing) they could look different or even (in the extreme case) be not available in the final version. Be aware.

To add Spock 1.0 as a dependency to your project define snapshot repository https://oss.sonatype.org/content/repositories/snapshots/ and the Spock artifact in version 1.0-groovy-2.0-SNAPSHOT. Sample configuration in Gradle:

repositories {
    ...
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}

dependencies {
    ...
    testCompile ('org.spockframework:spock-core:1.0-groovy-2.0-SNAPSHOT')
}

Summary

Mentioned extensions were designed for integration tests and because of class loader (or system) wide changes it is not safe to execute more than one test in the same time. Therefore it is important to separate pure, very fast and independent, unit tests from integration tests to (inter alia) allow unit tests to run in parallel.

After @Require and @IgnoreIf this is the second post about changes in upcoming Spock 1.0. The examples was written using Spock 1.0-groovy-2.0-SNAPSHOT and they can cloned from GitHub.

May the Spock be with you!

Introduction

Some tests (especially integration tests) should be run only if certain conditions are (or are not) met. Upcoming Spock 1.0 provides new @Requires and improved @IgnoreIf extensions to handle that requirement in a convenient way.

Historical background – waiting for Spock 1.0

The latest stable Spock version (0.7) has been released in October 2012 (~2 years as the time of writing). There have been made hundreds of commits to Git repository since then and many new features and improvements are already available in the current SNAPSHOT version. Unfortunately the “New and Noteworthy” section in the documentation doesn’t cover those changes and the only way (as I know) to get them know is digging into Git commits. As a Spock user I was curious what new is around the corner, so I did that job which resulted in the presentation at Confitura (in Polish). A as bonus I planned a series of blog entries describing those more interesting features and possibly also an update of Spock documentation.

This is just the first part of the changes in (upcoming) Spock 1.0. There is much more to discover and I will be presenting that in future blog posts.

New extension @Requires

@Requires allows to run given test (or the whole specification) only if given criteria are met.

    @Requires({ System.getProperty("os.arch") == "i386" })
    def "should use native libraries on 32-bit JVM"() { ... }

    @Requires({ env.containsKey("ENABLE_CRM_INTEGRATION_TESTS") })
    def "should do complicated things with CRM"() { ... }

It is opposite to already known from Spock 0.7 @Ignore extension which allowed to ignore the given test (or the whole specification) using access to system properties (propertiesSystem.getProperties()), environment variables (envSystem.getenv()) and java version (javaVersionSystem.getProperty("java.version")). In Spock 1.0 branch they both are much more powerful.

Testing my examples in practice I was surprised that a system property “os.arch” returns not a processor architecture taken from an OS, but a JVM version. So, be aware that running a 32-bit JVM on 64-bit system will return “i386”. Hopefully usually that knowledge is not important (unless for example the native libraries are used).

New features in @Requires and @IgnoreIf

In addition to the new @Requires extension it and its twin @IgnoreIf have got new internal abstraction to simplify the way how the operating system information and a JVM version can be accessed.

Operating system

Operating system information can be accessible in Spock 0.7 using os.name and os.version system properties. Unfortunately it can be complicated and error prone in some cases:

    //Run only on Linux and MacOS - in Spock 0.7 style
    @Requires({ System.getProperty("os.name").toLowerCase().contains("mac os") || 
                System.getProperty("os.name").toLowerCase().contains("darwin") || 
                System.getProperty("os.name").toLowerCase().contains("linux")  })
    def "should use fancy text console features"() { ... }

In the meantime Spock has got the new OperatingSystem abstraction which provides methods like:

    String getName() //Linux
    String getVersion() //8.1
    Family getFamily() //SOLARIS (enum)

    boolean isLinux()
    boolean isWindows()
    boolean isMacOs() //also Solaris and Other
    boolean iSolaris()
    boolean isOther()

With their help mentioned example can be simplified to very readable code precisely explaining our intentions:

    @Requires({ os.linux || os.macOs  })    //Spock 1.0 edition
    def "should use fancy text console features"() { ... }

JVM version

In addition to OperatatingSystem there is also Jvm abstraction which provides methods like:

    boolean isJava7() //true only if Java 7
    boolean isJava8Compatible() //true if Java 8+

or more generic:

    String getJavaVersion() //e.g. "1.8.0_05"
    String getJavaSpecificationVersion() //e.g. "1.8"

The original JVM version dependent test cases declaration:

    @IgnoreIf({ javaVersion < 1.8 })
    def "should find at runtime and use CompletableFuture for Java 8+"() { 
        ... 
    }

can be replaced with more verbose:

    @IgnoreIf({ !jvm.java8Compatible })
    def "should find at runtime and use CompletableFuture for Java 8+"() { 
        ... 
    }

Using static methods

@Requires (the same as @IgnoreIf) can also use static methods to define a condition (which is available, but less known in Spock 0.7). Those methods can be declared inside a given class, in an another class or (when using Groovy 2.3+) in a trait.

import static FancyFeatureRequiredIntranetConnectionSpecIT.isUrlAvailable

@Requires({ isUrlAvailable("http://some-host.intranet/") })
class FancyFeatureRequiredIntranetConnectionSpecIT extends Specification {

    //could be also from trait or other class
    static boolean isUrlAvailable(String url) { 
        //...
    }

    def "should do one thing in intranet"() { ... }

    def "should do another thing in intranet"() { ... }

    ...
}

Please pay attention to the static import in this example. Even though that code without an import looks ok and Idea sees the method it will fail at runtime with groovy.lang.MissingMethodException: No signature of method: (...). This is caused by the way how Spock internally tries to resolve references in a Closure. For detailed explanation see the next paragraph.

groovy.lang.MissingMethodException: No signature of method:
FancyFeatureRequiredIntranetConnectionSpecIT$_closure1.isUrlAvailable()
is applicable for argument types: (java.lang.String) values: [http://some-host.intranet/]

How does it internally work (for the curious)?

You may wonder how that code even compile if jvm or os are not known for the Specification class. The key thing is that code inside @Requires (and @IgnoreIf) annotation is wrapped with {} (curly brackets). In Groovy that syntax means “anonymous code block” and it is named Closure. The @Requires annotation accepts a Closure as a parameter:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@ExtensionAnnotation(RequiresExtension.class)
public @interface Requires {
  Class<? extends Closure> value(); // <- important line
}

Two important aspects of a Groovy Closure are used in Spock to implement those features:

  • a block of code is executed “at the later point”
  • an execution context can be delegated

The first point causes that Groovy compiler ignores unresolved references. At the compilation time the execution context can be unknown (a Closure can be passed as a parameter far away from the declaration place). The used references will be resolved at runtime and here the second point applies.

By default property references and methods are attempted to be resolved to the owner (an enclosing class or a surrounding Closure) and later to the delegate (by default the same as owner). A delegate can be changed and that is used in RequiresExtension:

    (...)
    condition.setDelegate(new PreconditionContext());
    condition.setResolveStrategy(Closure.DELEGATE_ONLY);
    return condition.call();

PreconditionContext is a delegate class for @Requires and @IgnoreIf providing an execution context. Its getOS() or getJvm() methods are resolved and executed when os or jvm properties are used in the annotation Closure. In addition to set a dedicated delegate, a resolve strategy is changed to not bother with an enclosing class and try resolve unresolved references only using PreconditionContext.

If you are new to Groovy and feel confused with the internals I propose you to take a look at the introduction to Groovy Closure. If you like it there is a lot more things to get know about Groovy Closure and its power.

Where can I find Spock 1.0?

Please notice that blog post is about features available in Git branch planned to become Spock 1.0 sometime in the future. They are currently available only in a 1.0-SNAPSHOT version in a separate repository. As not being released (as the time of writing) they could look different or even (in the extreme case) be not available in the final version. Be aware.

To add Spock 1.0 as a dependency to your project define snapshot repository http://oss.sonatype.org/content/repositories/snapshots/ and the Spock artifact in version 1.0-groovy-2.0-SNAPSHOT. Sample configuration in Gradle:

repositories {
    ...
    maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
}

dependencies {
    ...
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.0-SNAPSHOT'
}

Summary

New @Requires extension and the enhancements in @IgnoreIf are the first part of the series about new and noteworthy in upcoming Spock 1.0. When will it be released? Citing John Carmack “It’ll be done when it’s done”. If you would like to bring the release closer donate your time and contribute to the project.

Post written using Spock 1.0-groovy-2.0-SNAPSHOT. Examples can be cloned from GitHub.

Test quickly and prosper :).

Spock is a testing framework for Java and Groovy applications. It allows to write tests in highly expressive specification language which under the hood leverages Groovy compile-time metaprogramming capabilities (especially AST transformations).

Spock developers prefer flat test code formatting with empty lines:

class OrderedInteractionsSpec extends Specification {
  def "collaborators must be invoked in order"() {
    def coll1 = Mock(Collaborator)
    def coll2 = Mock(Collaborator)

    when:
    // try to reverse the order of these invocations and see what happens
    coll1.collaborate()
    coll2.collaborate()

    then:
    1 * coll1.collaborate()

    then:
    1 * coll2.collaborate()
  }
}

I, in turn, prefer more vertically compact formatting without empty lines, but with intend statements after label:

class OrderedInteractionsSpec extends Specification {
    def "collaborators must be invoked in order"() {
        given:
            def coll1 = Mock(Collaborator)
            def coll2 = Mock(Collaborator)
        when:
            // try to reverse the order of these invocations and see what happens
            coll1.collaborate()
            coll2.collaborate()
        then:
            1 * coll1.collaborate()
        then:
            1 * coll2.collaborate()
    }
}

Unfortunately my formatting style was not supported in IntelliJ Idea, even with idea-spock-enhancements plugin. This forced people like me to format it manually and pay attention to automatic code reformat.

Idea 13 provides a lot of new features and improvements. One of them is:

Label Formatting
Code style settings now let you specify custom indentation for the label blocks.

I have to admit I treated it as something not very important and until some time later when a colleague asked me if I know that feature I realized this is something I wanted.

With a simple configuration change Idea 13+ can be configured to support compact Spock specification formatting with code indentation. In File -> Settings (ALT-CTRL-S) -> Code Style -> Groovy set Label indent to 4 (or 2 if preferred) and Label indent style to Indent statements after label.

Spock test code formatting in Idea13

That is all. ALT-CTRL-L (Reformat code) becomes your friend again.

Btw, one more thing pointed out by @mariusz_s. By default labels in Idea looks like ordinal text. In Spock tests labels are part of the specification language and it would be nice to stand them out. It is possible with Spock Enhancements plugin for Idea which make the labels bold and colored.

Label highlighting with Spock plugin

The plugin provides also live inspections for block ordering errors which is very handy and I suggest it to all writing tests in Spock. Code long and prosper ;)

AssertJ and Awaitility are two of my favorites tools using in automatic code testing. Unfortunately until recently it was not possible to use it together. But then Java 8 entered the game and several dozens lines of code was enough to make it happen in Awaility 1.6.0.

Awaitility logo

AssertJ provides a rich set of assertions with very helpful error messages, all available though the fluent type aware API. Awaitility allows to express expectations of asynchronous calls in a concise and easy to read way leveraging an active wait pattern which shortens the duration of tests (no more sleep(5000)!).

The idea to use it together came into my mind a year ago when I was working on an algo trading project using Complex event processing (CEP) and I didn’t like to learn Hamcrest assertion just for asynchronous tests with Awaitility. I was able to do a working PoC, but it required to make some significant duplication in AssertJ (then FEST Assert) code and I shelved the idea. A month ago I was preparing my presentation about asynchronous code testing for the 4Developers conference and asked myself a question: How Java 8 could simplify the usage of Awaitility?

For the few examples I will use asynchronousMessageQueue which can be used to send ping request and return number of received packets. One of the ways to test it with Awaitility in Java 7 (besides proxy based condition) is to create a Callable class instance:

    @Test
    public void shouldReceivePacketAfterWhileJava7Edition() {
        //when
        asynchronousMessageQueue.sendPing();
        //then
        await().until(receivedPackageCount(), equalTo(1));
    }

    private Callable receivedPackageCount() {
        return new Callable() {
            @Override
            public Integer call() throws Exception {
                return asynchronousMessageQueue.getNumberOfReceivedPackets();
            }
        };
    }

where equalTo() is a standard Hamcrest matcher.

The first idea to reduce verbosity is to replace Callable with a lambda expression and inline the private method:

    @Test
    public void shouldReceivePacketAfterWhile() {
        //when
        asynchronousMessageQueue.sendPing();
        //then
        await().until(() -> asynchronousMessageQueue.getNumberOfReceivedPackets(), equalTo(1));
    }

Much better. Going forward lambda expression can be replaced with a method reference:

    @Test
    public void shouldReceivePacketAfterWhile() {
        //when
        asynchronousMessageQueue.sendPing();
        //then
        await().until(asynchronousMessageQueue::getNumberOfReceivedPackets, equalTo(1));
    }

Someone could go even further and remove Hamcrest matcher:

    @Test
    public void shouldReceivePacketAfterWhile() {
        //when
        asynchronousMessageQueue.sendPing();
        //then
        await().until(() -> asynchronousMessageQueue.getNumberOfReceivedPackets() == 1);  //poor error message
    }

but while it still works the error message becomes much less meaningful:

ConditionTimeoutException: Condition with lambda expression in
AwaitilityAsynchronousShowCaseTest was not fulfilled within 2 seconds.

instead of very clear:

ConditionTimeoutException: Lambda expression in AwaitilityAsynchronousShowCaseTest
that uses AbstractMessageQueueFacade: expected  but was  within 2 seconds.>

The solution would be to use AssertJ assertion inside lambda expression:

    @Test
    public void shouldReceivePacketAfterWhileAssertJEdition() {
        //when
        asynchronousMessageQueue.sendPing();
        //then
        await().until(() -> assertThat(asynchronousMessageQueue.getNumberOfReceivedPackets()).isEqualTo(1));
    }

and thanks to the new AssertionCondition initially hacked within a few minutes it became a reality in Awaitility 1.6.0. Of course AssertJ fluent API and meaningful failure messages for different data types are preserved.

As a bonus all assertions that throw AssertionError (so particularly TestNG and JUnit standard assertions) can be used in the lambda expression as well (but I don’t know anyone who came back to “standard” assertion knowing the power of AssertJ).

The nice thing is that the changes itself leverage Runnable class to implement lambdas and AssertJ support and Awaitility 1.6.0 is still Java 5 compatible. Nevertheless for the sake of readability it is only sensible to use the new constructions in Java 8 based projects.

Update. Be aware that in the meantime until() has been renamed to untilAsserted().

Btw, here are the “slides” from my presentation at 4Developers.

4developers logo

Mockito uses a lazy approach for stubbing and when a not stubbed method is called it returns a default value instead of throwing an exception (like EasyMock). This is very useful to not overspecify the test.

A default returned value depends on a return type of a stubbed method. For methods eturning collections we have an empty collection, for numbers – 0, for booleans false, for ordinary objects – null (in Mockito 2.0 the set of not null values will be extended – this can be also achieved with 1.9.x and ReturnsMoreEmptyValues answer).

Mockito logo

Before we go any further a quick introduction do Answers (you can skip to the next paragraph if Answers are for you like an open book). In addition to simple stubbing based on desired value passed to Mockito directly:

given(tacticalStationMock.getNumberOfTubes())
    .willReturn(TEST_NUMBER_OF_TORPEDO_TUBES);

or for consecutive calls:

given(tacticalStationMock.getNumberOfEnemyShipsInRange()).willReturn(2, 3);

the stubbing API provides a way to pass an object with the logic to determine what should be returned in given case (based on method arguments or even an internal state (for consecutive calls)). A simple practical example returning always the first parameter passed to the called method:

public class ReturnFirstArgumentAnswer implements Answer<Object> {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        Object[] arguments = invocation.getArguments();
        if (arguments.length == 0) {
            throw new MockitoException("...");
        }
        return arguments[0];
    }
}

A sample usage when stubbing:

given(mock.methodToStub("arg1", "arg2"))
    .willReturn(new ReturnFirstArgumentAnswer());

Mockito provides a set of build-in answers. Some of them (like ThrowsException or CallRealMethods) are used by Mockito internally, but some others (like ReturnsArgumentAt introduced in 1.9.5) can be also useful for developers writing tests.

Let’s return to the main topic. Sometimes it is useful to change those default values. In addition to using the answer mechanism for stubbing a specific method calls Mockito provides a way to specify an answer which will be used for every not stubbed method execution on given mock. To do so we can use a static mock() method which in addition to a class to mock takes an additional parameter – a default answer.

mock(SpaceShip.class, Mockito.RETURNS_DEFAULTS);

As returns defaults is a default behavior in Mockito above code is just a more explicit version of:

mock(SpaceShip.class);

but we can use this construction to achieve a few interesting behaviors. One of the predefined answers provided by Mockito is RETURNS_DEEP_STUBS. It causes an automatic stubbing of chained methods calls and allows to do following:

SpaceShip spaceShipMock = mock(SpaceShip.class, Mockito.RETURNS_DEEP_STUBS);
given(spaceShipMock.getTacticalStation().getNumberOfTubes()).willReturn(5);

Please note that with default configuration it would cause NullPointerException due to the fact spaceShipMock.getTacticalStation() returns null. With RETURNS_DEEP_STUBS Mockito under the hood creates a mock for every middle method call. This is an equivalent of:

//NOTE. Deep stubs implemented manually - no more needed with RETURNS_DEEP_STUBS.
//See the previous example with an equivalent functionality in 2 lines.
SpaceShip spaceShipMock = mock(SpaceShip.class);
TacticalStation tacticalStationMock = mock(TacticalStation.class);
given(spaceShipMock.getTacticalStation()).willReturn(tacticalStationMock);
given(tacticalStationMock.getNumberOfTubes()).willReturn(5);

As a bonus, deep stubbing allows to perform a verification (only) on the last mock in the chain:

verify(spaceShipMock.getTacticalStation()).getNumberOfTubes();

Another provided answer is RETURNS_MOCKS. This tries to return default value using ReturnsMoreEmptyValues answer (an extended version of a default ReturnsEmptyValues), but if it fails a mock is returned. Only in the situation where the return type cannot be mocked (e.g. is final) null is returned.

mock(OperationsStation.class, Mockito.RETURNS_MOCKS);

Sometimes it can be useful to stub specified methods, but delegate remaining calls to the real implementations. It can be done with CALLS_REAL_METHODS. It can be useful for example when testing an abstract class (just the implemented methods without the need to subclass to create a concrete subclass).

mock(AbstractClass.class, Mockito.CALLS_REAL_METHODS);

Please note that using RETURN_DEEP_STUBS, RETURN_MOCKS and CALLS_REAL_METHODS should be not needed when dealing with well crafted code, written with the usage of Test-Driven Development. Nevertheless sometimes it is required to write tests for legacy code before a try to refactor it.

From a set of default answers defined in Mockito.java, there is also a very useful RETURNS_SMART_NULLS option. This returns SmartNull class instance instead of plain null, which provides a hint which mock stubbing was not performed correctly (and caused NPE). I wrote more about this mode some time ago in Beyond the Mockito Refcard #1.

In addition to define a default answer we can use any class which implements org.mockito.stubbing.Answer interface – both provided by Mockito or hand written. One more tip. In case you would like to use RETURNS_SMART_NULLS or ReturnsMoreEmptyValues globally for all mocks in your application you can check a trick with MockitoConfiguration.

Btw, in case you are starting an adventure with Mockito or want to learn more or just want to organize your knowledge you can be interested in my Mockito Refcard available for free from dzone.com.

Btw2, in addition if you are new to Mockito and live near Warszawa you can consider an attendance in my lecture/workshop about Mockito at Jinkubator – 18 II 2014 (next Tuesday).

Jinkubator

This post is the fourth part of the series Beyond the Mockito refcard extending released some time ago my Mockito reference card.

Recently there was an interesting and unusual event in Warsaw for all enthusiasts of testing – “6 tastes of testing – flashtalks“. Instead of one long presentation common for WJUG meetings 6 guys gave 6 flashtalks (~15 minutes long presentations) about different aspects of testing.

The audience could listen about:

  • Fest Assertions – a set of assertions with fluent API for TestNG and JUnit by Michał Lewandowski,
  • JUnitPrams – a better way to write parameterized tests with JUnit by Paweł Lipiński,
  • Spock – a setting new standards testing framework for Java and Groovy code by Jakub Nabrdalik,
  • Geb – a Groovy way for acceptance testing with Web Driver and Page Object Pattern by Tomasz Kalkosiński,
  • asynchronous calls testing with Awaitility by Marcin Zajączkowski (a.k.a. me),
  • the idea how to use IoC and Guice in tests by Paweł Cesar Sanjuan Szklarz.

On my own speach I performed an experiment with a presentation format. Instead of a classical Impress/Power Point slides I used Vym – View Your Mind – an interesting tool for mind mapping with a build in slide editor. It allowed me to “animate” my mind map and talk about every its point (node). By the way I reported a dozen of feature requests for Vym, so there is a chance to make a slide editor even better on the next presentation :). The downside of using such tool is a limited way how it could be exported to some neutral format. The picture below contains the whole map, but without code snippets.

Sleepless asynchronous calls testing with Awaitility

The people I asked were pleased with the presentations. They were cross-sectional and touched many different aspects briefly, but even though I knew covered topics before I noted down a few useful tips. The venue was tightly filled (about 100 people). In addition to interesting topics there were an ability to eat pizza and win an SSD disk. The event was completed with a networking session in the near restaurant. For those who cannot attend there is a video available (in Polish) on the WJUG’s You Tube channel.

Recently I wanted to configure an ability to run both TestNG and JUnit tests in one Maven module (project). At the end I managed how to do it clean and short, but before that I have found a few different solutions on the web (top 5 in Google) which part of them didn’t work and the rest applied to the earlier versions of Surefire plugin and was overly complicated (e.g. two separate executions). Therefore I decided to write this short post to show how it could be done in Surefire 2.13 – the newest version available in March 2013.

Mixing those tests frameworks in one module can be done just by adding both JUnit and TestNG as a plugin dependencies (not as project dependencies):

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-testng</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
</plugin>

As the result both test types are executed.

[INFO] --- maven-surefire-plugin:2.13:test (default-test) @ junit-testng-poc ---
[INFO] Surefire report directory: /tmp/junit-testng-poc/target/surefire-reports
[INFO] Using configured provider org.apache.maven.surefire.junitcore.JUnitCoreProvider
[INFO] Using configured provider org.apache.maven.surefire.testng.TestNGProvider

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
parallel='none', perCoreThreadCount=true, threadCount=2, useUnlimitedThreads=false
Running info.solidsoft.rnd.junit.testng.SampleJUnitTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.253 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0


-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
Configuring TestNG with: TestNG652Configurator
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.869 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Why to use TestNG with JUnit together? TestNG has a few features which are unavailable or less flexible in JUnit (just to mention a few: dependencies between tests and groups of tests (irreplaceable for integration tests with long startup), parametrized tests, concurrent execution or per suite/group/class init/shutdown operations). Therefore it is tempting to migrate existing tests from JUnit to TestNG. Having large code base it could be not so easy to migrate all of them at once and presented configuration allows to write the new tests in TestNG and rewrite the old tests when appropriate.

The whole working example can be found in my GitHub repository.

Btw, it is worth to mention that thanks to the fact TestNG generates reports also in the JUnit’s XML format all the tools compatible with JUnit (Jenkins, Sonar, …) will merge test results from JUnit and TestNG and display all of them properly.

Btw2, the same configuration works also with Failsafe plugin.

Btw3, thanks to the fact Spock Framework is under the hood a runner for JUnit presented trick can be used also to mix it with TestNG. This requires some additional work to integrate also Groovy and I plan to write about it in one of my future posts.

Mutation testing can efficiently detect places in code which are insufficiently covered by tests. The price we have to pay for it is time – number of mutations has to be tested with a set of unit tests. This time is much longer than calculating a “normal” code coverage. The newest PIT 0.29 provides a long awaiting feature – incremental analysis. When enabled PIT will store results from the previous runs on disk and track changes in the code and tests to avoid rerunning analyses which result should stay the same.

To start using incremental analysis it is necessary set historyInputLocation and historyOutputLocation configuration properties. For example in Pitest Maven Plugin it could be:

<plugin>
    <groupId>org.pitest</groupId>
    <artifactId>pitest-maven</artifactId>
    <version>0.29</version>
    <configuration>
        <threads>4</threads>
        <historyInputLocation>target/pitHistory.txt</historyInputLocation>
        <historyOutputLocation>target/pitHistory.txt</historyOutputLocation>
    </configuration>
</plugin>

It is worth to notice that for a basic usage (i.e. run analysis from time to time) input and output history locations will point to the same file. Therefor in Gradle plugin for PIT 0.29.0 there was added an additional parameter enableDefaultIncrementalAnalysis which when enabled automatically set historyInputLocation and historyOutputLocation to build/pitHistory.txt simplifying a configuration.

buildscript {
    (...)
    dependencies {
        classpath 'info.solidsoft.gradle.pitest:gradle-pitest-plugin:0.29.0'
        classpath 'org.pitest:pitest:0.29'
    }
}

apply plugin: 'pitest'

pitest {
    targetClasses = ['our.base.package.*']
    threads = 4
    enableDefaultIncrementalAnalysis = true
}

There is a number of optimizations already implemented in PIT. The author warns of potential errors which can be introduced in that way into the analysis, but although being currently an experimental feature it can dramatically reduce calculation time especially when used on very large codebases.

Update 2013-04-13: Added missing line which applies plugin to a project. Thanks to Bruno de Carvalho for report the issue.