Sharing knowledge

Migration to hugo completed

Good news, everyone. Migration from octopress to hugo was completed. If you find any broken layout and/or links, please contact me.

Refresh

Ok, hopefully I will start blog again soon.

Using Unitils ReflectionAssert

Often it is needed to compare two different instances of the class inside test. I.e. we save object into database, then fetch it back from db and we want to be sure if nothing was lost during saving/reading.

In order to make such assertions more easier and maintainable one can use great Unitils library which has useful class ReflectionAssert

First, update parent’s pom.xml:

<properties>
    <unitils.version>3.4</unitils.version>
</properties>
<dependency>
    <groupId>org.unitils</groupId>
    <artifactId>unitils-core</artifactId>
    <version>${unitils.version}</version>
    <scope>test</scope>
</dependency>

Then add dependency to the child module:

<dependency>
    <groupId>org.unitils</groupId>
    <artifactId>unitils-core</artifactId>
</dependency>

Usage is very simple: Add static import to the class.

import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;

and use it instead of regular JUnit assert:

assertReflectionEquals(expected, actual);

It is possible to pass reflection comparator modes as optional parameters to the above method.

Be ware that this method is not very useful if you want to compare objects which has floating point or double parameters - ReflectionAssert compares double and float values using ==, so it is not very useful. It is not possible to pass epsilon for comparison.

excerpt from org.unitils.reflectionassert.comparator.impl.LenientNumberComparator#compare:

Double leftDouble = getDoubleValue(left);
Double rightDouble = getDoubleValue(right);
if (!leftDouble.equals(rightDouble)) {
    return new Difference(differenceMessage, left, right);
}

If you need to compare double values in JUnit assertions then it is better to use hamcrest library.

import static org.hamcrest.number.IsCloseTo.closeTo;
import static org.junit.Assert.assertThat;

// in @Test method:
assertThat(actual.getFederalIncomeTax(), closeTo(expected.getFederalIncomeTax(), EPSILON))

Happy hacking!

Using AssertJ

AssertJ is a library which provides fluent strongly-typed assertions to use in unit tests.

Example of assertions written with AssertJ:

import io.github.uthark.blog.assertj.Assertions.assertThat;

// ... within @Test
User result = userDao.findByLogin("username");
assertThat(result).
    isNotNull().
    isActive().
    hasLogin("username");

As you can see assertions look much more readable. The integration of assertj into Maven project is very easy:

  1. Update pom.xml in parent module
<properties>
    <assertj-core.version>1.6.0</assertj-core.version>
    <assertj-assertions-generator-maven-plugin.version>1.2.0</assertj-assertions-generator-maven-plugin.version>
</properties>

<dependencyManagement>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>${assertj-core.version}</version>
        <scope>test</scope>
    </dependency>
</dependencyManagement>

<pluginManagement>
    <plugin>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-assertions-generator-maven-plugin</artifactId>
        <version>${assertj-assertions-generator-maven-plugin.version}</version>
        <executions>
            <execution>
                <id>generate-assertions</id>
                <phase>generate-test-sources</phase>
                <goals>
                    <goal>generate-assertions</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

</pluginManagement>
  1. Update pom.xml in child module
<dependencies>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-assertions-generator-maven-plugin</artifactId>
            <configuration>
                <!-- you can define collection packages: -->
                <packages>
                    <param>io.github.uthark.blog.assertj</param>
                </packages>

                <!-- Or specify classes one by one. -->
                <classes>
                    <param>io.github.uthark.blog.assertj.User</param>
                </classes>
            </configuration>
        </plugin>
    </plugins>
</build>

After this changes it is possible to generate assertions for the classes you want test:

mvn assertj:generate-assertions

By default assertj will generate assertion classes in target/generated-test-sources/assertj-assertions/, it is possible to override this behaviour by passing configuration element targetDir to plugin.

Additonal documentation for Maven plugin can be found here

Happy hacking!

Initializing Mockito @Mocks with JUnit @Rule

In this post I will show how one can implement custom JUnit @Rule.

As an example let’s take Mockito and implement custom rule which will initialize Mocks in test class.

By default, Mockito provides the following methods of mock initialization:

  1. Using Mockito.mock

    Initialize mocks with Mockito.mock:

    public void FooTest {
            
        private Foo foo;
    
        @Before
        public void setUp() {
            FooDependency dep = Mockito.mock(FooDependency.class);
            foo = new Foo(dep);
        }
    }

    This is the simplest case.

  2. Using MockitoAnnotations. Initialize mocks with MockitoAnnotations:

    public void FooTest {
            
        private Foo foo;
    
        @Mock
        private FooDependency dep;
    
        @Before
        public void setUp() {
            MockitoAnnotations.initMocks(this);
            foo = new Foo(dep);
        }
    }

    This method is useful when you have a lot of mocks to inject.

  3. Using MockitoJUnitRunner

    Initialize mocks with MockitoJUnitRunner:

    @RunWith(MockitoJUnitRunner.class)
    public void FooTest {
            
        private Foo foo;
    
        @Mock
        private FooDependency dep;
    
        @Before
        public void setUp() {
            foo = new Foo(dep);
        }
    }

I want to show you another option, by using custom JUnit @Rule.

First, we need to implement TestRule interface which allows to implement custom behaviour during test execution:

MockitoInitializerRule:

public class MockitoInitializerRule implements TestRule {
    private Object test;

    public MockitoInitializerRule(Object test) {
        this.test = test;
    }

    @Override
    public Statement apply(Statement base, Description description) {
        return new MockitInitilizationStatement(base, test);
    }
}

We need to pass current test class instance to the rule, so it will be possible inject mocks into class instance. Actual implementation of our rule will go to new class - subclass of Statement:

MockitInitilizationStatement:

public class MockitInitilizationStatement extends Statement {
    private final Statement base;
    private Object test;

    MockitInitilizationStatement(Statement base, Object test) {
        this.base = base;
        this.test = test;
    }

    @Override
    public void evaluate() throws Throwable {
        MockitoAnnotations.initMocks(test);
        base.evaluate();
    }
}

What we do is basically initialize mocks in the test class and then proceed with the test method execution.

Now, let’s take a look at the usage of newly created Rule:

Example usage of MockitoInitializerRule:

public void FooTest {
    
    private Foo foo;

    @Mock
    private FooDependency dep;

    @Rule
    public TestRule mockitoInitializerRule = new MockitoInitializerRule(this);

    @Before
    public void setUp() {
        foo = new Foo(dep);
    }
}

Comparing to variant with MockitoJUnitRunner this one provides ability to use custom Runner, i.e. we can continue to use SpringJUnit4ClassRunner

Atom.io invites

If anyone needs invites to atom.io, text editor from github - ask me in comments. I do have 3 invites to share.