Tag Archives: Unit Testing

How to verify equality without equals method

twittergoogle_plusrss

Facebooktwittergoogle_plusredditlinkedinmail

I don’t like equals method. It often requires very ugly code. Therefore I try to avoid need for it as much as possible. But how to compare objects during testing? This blog post will cover it.

You may argue, that there are various possibilities to generate equals method or make it more maintainable. For example:

But what about testing it? I met so many developers that were surprised after hearing about unit testing of equals method. So should we unit test it? YES, of course! If it’s generated by IDE, it often has a lot of null check if statements. Testing such code means covering a lot of test scenarios. Also static code analyzer will probably complain about cyclomatic complexity violations.

If you are using object with custom equals method in HashMap or HashSet, we need to conform to hashCode vs equals contract. Eventual issues in this contract can lead into very tricky behavior of our map or set. Therefore I rather use some unique String or numeric representation as key in the map so that I don’t need to create equals. HashSet is type I try to avoid completely.

So if most common reasons for creating equals method for production code are avoided, what about testing? Verifications in tests often require to compare if objects have fields with same values. Of course it doesn’t make sense to create equals only for testing assertions. Sometimes we also have nested types to compare. And what about comparison of arrays or lists during testing?

Luckily there is very neat library called Unitils. It provides various testing helpers for Hibernate, Database and I/O testing or mocking. But I was using only module called Reflection assert. It makes comparison of Java objects during testing piece of cake.

Example Objects

package net.lkrnac.blog.reflectioncompare;

public class Address {
    private String line1;
    private String line2;
    private String city;
    private String postalCode;

    public Address(String line1, String line2, String city, String postalCode) {
        this.line1 = line1;
        this.line2 = line2;
        this.city = city;
        this.postalCode = postalCode;
    }

    public String getLine1() {
        return line1;
    }

    public String getLine2() {
        return line2;
    }

    public String getCity() {
        return city;
    }

    public String getPostalCode() {
        return postalCode;
    }
}
package net.lkrnac.blog.reflectioncompare;

public class Person {
    private String firstName;
    private String lastName;
    private Address address;

    public Person(String firstName, String lastName, Address address) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Address getAddress() {
        return address;
    }
}

Notice that Address is nested field in Person class.

Reflection equals verification

Now let’s take a look how we would compare instances of above listed types.

package net.lkrnac.blog.reflectioncompare;

import org.junit.Test;

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

public class VerifyObjectsTest {
    @Test
    public void testObjectsSuccess() {
        Address expectedAddress = new Address("Barad-dûr", "Mount Doom", "Mordor", "1");
        Person expectedPerson = new Person("Sauron", null, expectedAddress);

        Address actualAddress = new Address("Barad-dûr", "Mount Doom", "Mordor", "1");
        Person actualPerson = new Person("Sauron", null, actualAddress);

        assertReflectionEquals(expectedPerson, actualPerson);
    }

    @Test
    public void testObjectsFail() {
        Address expectedAddress = new Address("Barad-dûr", null, "Mordor", "1");
        Person expectedPerson = new Person("Sauron", null, expectedAddress);

        Address actualAddress = new Address("Barad-dûr", "Mount Doom", "Mordor", "1");
        Person actualPerson = new Person("Sauron", null, actualAddress);

        assertReflectionEquals(expectedPerson, actualPerson);
    }
}

First test method created two separate instances of Person and compares them. Second test method intentionally creates difference in nested Address field between actual and expected, so that we can explore Unitils output:

junit.framework.AssertionFailedError: 
Expected: Person<firstName="Sauron", lastName=null, address=Address<line1="Barad-dûr", line2=null, city="Mordor", postalCode="1">>
  Actual: Person<firstName="Sauron", lastName=null, address=Address<line1="Barad-dûr", line2="Mount Doom", city="Mordor", postalCode="1">>

--- Found following differences ---
address.line2: expected: null, actual: "Mount Doom"

--- Difference detail tree ---
 expected: Person<firstName="Sauron", lastName=null, address=Address<line1="Barad-dûr", line2=null, city="Mordor", postalCode="1">>
   actual: Person<firstName="Sauron", lastName=null, address=Address<line1="Barad-dûr", line2="Mount Doom", city="Mordor", postalCode="1">>

address expected: Address<line1="Barad-dûr", line2=null, city="Mordor", postalCode="1">
address   actual: Address<line1="Barad-dûr", line2="Mount Doom", city="Mordor", postalCode="1">

address.line2 expected: null
address.line2   actual: "Mount Doom"

Very nice output making the nested difference very obvious.

Comparison of arrays and collections

Another very useful use case of Unitils Reflections assert module is comparison of arrays and collections:

package net.lkrnac.blog.reflectioncompare;

import org.junit.Test;
import org.unitils.reflectionassert.ReflectionComparatorMode;

import static java.util.Arrays.asList;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;

public class VerifyArraysTest {

    @Test
    public void testCompareArraysSuccess() {
        String [] expectedArray = new String []{"string1", "string2", "string3"};
        String [] actualArray = new String []{"string1", "string3", "string2"};

        assertReflectionEquals(expectedArray, actualArray, ReflectionComparatorMode.LENIENT_ORDER);
    }

    @Test
    public void testCompareArraysFail() {
        String [] expectedArray = new String []{"string1", "string2", "string3"};
        String [] actualArray = new String []{"string1", "string3", "string2"};

        assertReflectionEquals(expectedArray, actualArray);
    }

    @Test
    public void testCompareCollectionsSuccess() {
        String [] expectedArray = new String []{"string1", "string2", "string3"};
        String [] actualArray = new String []{"string1", "string3", "string2"};

        assertReflectionEquals(asList(expectedArray), asList(actualArray), ReflectionComparatorMode.LENIENT_ORDER);
    }

    @Test
    public void testCompareCollectionsFail() {
        String [] expectedArray = new String []{"string1", "string2", "string3"};
        String [] actualArray = new String []{"string1", "string3", "string2"};

        assertReflectionEquals(asList(expectedArray), asList(actualArray));
    }
}

First test method is comparing arrays. It will succeed, because we instructed Unitils to ignore order of elements with parameter ReflectionComparatorMode.LENIENT_ORDER. In second test method, we don’t use reflection comparator mode parameter, so order matters. Because it’s is different for actual and expected arrays, test will fail with this output:

junit.framework.AssertionFailedError: 
Expected: ["string1", "string2", "string3"]
  Actual: ["string1", "string3", "string2"]

--- Found following differences ---
[1]: expected: "string2", actual: "string3"
[2]: expected: "string3", actual: "string2"

--- Difference detail tree ---
 expected: ["string1", "string2", "string3"]
   actual: ["string1", "string3", "string2"]

[1] expected: "string2"
[1]   actual: "string3"

[2] expected: "string3"
[2]   actual: "string2"

Again very detailed output about test failure.

Lastly there are also included test methods comparing lists. So Unitils Reflection assert module can be easily used also for Java collections.

Example code is hosted on Github.

twittergoogle_plusrss

Verifying DateTime and Date with Hamcrest

twittergoogle_plusrss

Facebooktwittergoogle_plusredditlinkedinmail

Since I started diving into automated testing and practicing TDD, verification of date values was pain. Luckily there is nice library for legacy Date and new Java 8 DateTime APIs, which cures this pain.

If you belong to healthier part of Java development community and practicing unit testing on daily basis, you probably are aware of Hamcrest Java library. It can make your tests much more readable. It’s architecture is very modular and is used by various other testing libraries.

Major part of it’s flexibility is it concept of Matcher. I am not going to dive into this concept now. If you are not familiar, just take a quick look at Hamcrest tutorial. One of the matcher you can plug into your testing toolbox is library hamcrest-date. With this library we can easily test that date was generated within certain range:

    @Test
    public void validateDate() {
        //GIVEN
        Date expectedDate = new Date();

        //WHEN
        Date actualDate = new Date();

        //THEN
        assertThat(actualDate, DateMatchers.within(2, ChronoUnit.SECONDS, expectedDate));
    }

We can do that also for Java 8 types:

    @Test
    public void validateDateTime() {
        //GIVEN
        LocalDateTime expectedDateTime = LocalDateTime.now();

        //WHEN
        LocalDateTime actualDateTime = LocalDateTime.now();

        //THEN
        assertThat(actualDateTime, LocalDateTimeMatchers.within(2, ChronoUnit.SECONDS, expectedDateTime));
    }

Or pick various exotic verifications hamcrest-core library provides:

    @Test
    public void validateZonedDateTime() {
        //GIVEN
        ZonedDateTime expectedDateTime = ZonedDateTime.of(2016, 3, 20, 13, 3, 0, 0, ZoneId.of("GMT+1"));

        //WHEN
        ZonedDateTime actualDateTime = ZonedDateTime.of(2016, 3, 20, 13, 3, 0, 0, ZoneId.of("GMT-0"));

        //THEN
        assertThat(actualDateTime, ZonedDateTimeMatchers.sameDay(expectedDateTime));
        assertThat(actualDateTime, ZonedDateTimeMatchers.after(expectedDateTime));
        assertThat(actualDateTime, ZonedDateTimeMatchers.isSunday());
        assertThat(actualDateTime, ZonedDateTimeMatchers.isMarch());
    }

Kudos to creator for this nice little library. This example is hosted in Github.

twittergoogle_plusrss
Mastering Unit Testing Using Mockito and JUnit

Book Review: Mastering Unit Testing Using Mockito and JUnit

twittergoogle_plusrss

Facebooktwittergoogle_plusredditlinkedinmail

I was asked by Packt Publishing to write a review blog post about the new book Mastering Unit Testing Using Mockito and JUnit by Sujoy Acharya (released in Jun 2014). As I am passionate about all topics around testing or continuous development, I got exited. Nice side effect of this is that I could read this book for free ;). Book is 314 pages long. Divided into 10 chapters.

Preface

Summarizes why reader wants to test. Also why wants to have automated feedback loop. But there was very strong statement: “Greenfield projects always follow test-driven development to deliver maintainable and testable code.” Of course author probably wrote this before test first / test last battle. I am personally also TDD infected but there are definitely situations where it doesn’t make sense to do test first or test at all (e.g. prototyping). Also we should accept existence of test last approach. There are certainly very strong TDD opponents:

Chapter 1: JUnit4 – A Total recall

Guides reader how to create simple project in Eclipse. Leads him through JUnit features. It starts with basic fundamentals. Later in the chapter are described advanced parts of JUnit API. Some of these parts of the API should be used rarely or not at all (e.g. test methods ordering). This would be worth mentioning for beginners.  I wasn’t very excited because I am TestNG user. If you ever wrote some unit tests you probably would want to skip this chapter. Surprising for me was comparison of JUnit 4 @Before annotation with JUnit 3 setUp(). JUnit 4 is already 8 years old.

Chapter 2: Automating JUnit Tests

Elaborates about Continuous Integration. Also provides basic information about Gradle, Maven and Ant. Demonstrates very simple configurations of each build tool and how they run tests. Lastly touches simple Jenkins integration with each mentioned tool. Shame that configuration of examples across the book weren’t driven by any of this build tools.

Chapter 3:  Test Doubles

Brief explanation of theory behind faking dependencies of testing object. It also contains examples of each type (without usage of any testing framework so far).

Chapter 4: Progressive Mockito

Demonstrates Mockito syntax on examples. It goes through basic and also advanced Mockito features. At the end of the chapter is mentioned BDD (Behavioral driven development) style of testing. The only disturbing moment was manual inclusion of dependencies in example project configuration. Build tools were discussed in Chaper 2.

Chapter 5: Exploring Code Coverage

Author explains what code coverage means. After that shows some ways how to measure code coverage from Eclipse. I was surprised that he still accepts Cobertura as relevant tool, because Cobertura is dead project now. Last version was working only for Java 6. Java 6 was marked as “End of life” more that a year ago. That is why integration examples of Cobertura with Ant and Maven aren’t very useful. Examples how to integrate them with JaCoCo would be much more appropriate. I integrated JaCoCo with Maven in the past. It’s definitely doable.

EDIT: Cobertura is again under active development and is working for Java 7 now.

Chapter 6: Revealing Code Quality

This chapter shows three very useful Java static code analyzers

  • PMD
  • FindBugs
  • CheckStyle

Than it introduces SonarQube and its integration with mentioned build tools. It is very handy tool for monitoring technical depth on the project.

Chapter 7: Unit Testing the Web Tier

Some examples how you can test

  • Servlets
  • Spring MVC

But Spring MVC examples with Spring Test’s MockMvc library are missing. Examples in this chapter contain only plain Mockito + JUnit libraries. Readers should definitely take a look at MockMvc capabilities, because they are much more handier than explained approach.

Chapter 8: Playing with Data

This time author focuses on DAO layer. My personal opinion is that mocking Connetion or PreparedStatement in tests isn’t quite right. You can have test passing, but when you execute SQL statement against DB it can fail on some SQL error. I prefer to have integration tests for DAO layer.

Chapter 9: Solving Test Puzzles

Discusses constructs known as testability killers and some approaches how to solve them. I also discussed this topic in blog post series. I am glad that author doesn’t suggest usage of PowerMock. Rather takes the path of changing production code to enhance testability. Totally agree. Finally it shows example of TDD style of programming. Shame that this is the only example in the book where test is introduced before production code. So all other examples doesn’t follow TDD.

Chapter 10: Best Practices

This chapter dives into some common pitfalls reader can fall during writing the tests. Such advices are always good to keep in mind.

Conclusion

“Mastering Unit Testing Using Mockito and JUnit” book declares that was written for advanced to novice software testers and developers who use Mockito and JUnit framework. I would say that is only for beginners. It is mainly because book is covering wide range of topics around testing and its automation. There isn’t enough place dive deeply. Positive is covering nearly all aspects of professional unit testing. So it is very good start for developers that are willing to explore benefits of automated feedback loop. Author takes approach of hands on examples, so it is much better to read it next to the computer.

twittergoogle_plusrss

Why is wide usage of PowerMock problematic

twittergoogle_plusrss

Facebooktwittergoogle_plusredditlinkedinmail

There are Java constructs well known for their testability issues:

  • Private methods
  • Static methods
  • Constuctors
  • Final methods or classes

Skilled Java developer following TDD tries to minimize their testability impacts. Don’t want to dive into techniques to enhance testability. They are explained well on Misko Hevery’s blog.

Some developers argue that we have frameworks today (like PowerMock or JMockIt) that are able mock these testability killers. And it’s true. So should we throw factory methods to bin and start using static or singleton classes widely? The answer is NO. Reason is in Java language nature. There isn’t way how to mock mentioned constructs using Java features like inheritance, polymorphism or reflection. Byte-code manipulation is needed. And that is the problem.

Here are some facts about PowerMock:

  • It is using Javassist library for byte-code manipulation
  • It took 1.5 years to make PowerMock + Javaassist compatible with Java7 since its introduction. Here is note from PowerMock change log:
Change log 1.5 (2012-12-04)
---------------------------
Upgraded to Javassist 3.17.1-GA, this means that PowerMock works in Java 7!

I tried to use PowerMock and JMockIt to test some legacy code. The result weren’t acceptable for me. Sometimes there were some strange crashes or clash with JaCoCo test coverage tool (have to say that I didn’t give JMockIt deep chance and abandoned on it immediately after first problems). At the end I always decided to change the production code to enhance testability and use plain Mockito.

If it would be up to me I would exclude byte-code manipulation testing frameworks from technology stack completely. Java8 is coming soon and potential migration of unit tests can be a big problem if it is used widely. It would be ridiculous to wait 1.5 years for Java8 update because of testing framework.

I respect PowerMock and JMockIt projects and people behind them. They are sometimes valuable in cases when you have to deal with legacy code or third party libraries.

twittergoogle_plusrss

Mock final class

twittergoogle_plusrss

Facebooktwittergoogle_plusredditlinkedinmail

Foreword

If you already read some other blog post about unusual mocking, you can skip prelude via this link.

I was asked to put together examples how to mock Java constructs well know for their testability issues:

I am calling these techniques unusual mocking. I was worried that such examples without any guidance can be widely used by teammates not deeply experienced in mocking frameworks.

Developers practicing TDD or BDD should be aware of testability problems behind these constructs and try to avoid them when designing their tests and modules. That is the reason why you probably wouldn’t be facing such unusual mocking often on project using these great programming methodologies.

But sometimes you have to extend or maintain legacy codebase that usually contains low cohesive classes. In most cases there isn’t time in current hectic agile world to make such class easy to unit test standard way. When you are trying to unit test such class you often realize that unusual mocking is needed.

That is why I decided to create and share refactoring considerations alongside with examples and workarounds for unusual mocking. Examples are using Mockito and PowerMock mocking frameworks and TestNG unit testing framework.

Mock final class

Refactoring considerations

Change class to non-final (remove final keyword) and test it standard way. This is technique I use always when I can change code of final class.

Usage of PowerMock

Before usage of this example, please carefully consider if it is worth to bring bytecode  manipulation risks into your project. They are gathered in this blog post. In my opinion it should be used only in very rare and non-avoidable cases.

Test shows how to mock final class by PowerMock framework. Example covers:

  1. Mocking of method with return value in final class
  2. Mocking of final void method in final class
  3. Verifying of method calls in final class

Final class:

public final class Plane {
	public static final int ENGINE_ID_RIGHT = 2;
	public static final int ENGINE_ID_LEFT = 1;

	public boolean verifyAllSystems() {
		throw new UnsupportedOperationException("Fail if not mocked!");
	}

	public void startEngine(int engineId) {
		throw new UnsupportedOperationException(
				"Fail if not mocked! [engineId=" + engineId + "]");
	}
}

Class under test:

public class Pilot {
	private Plane plane;

	public Pilot(Plane plane) {
		this.plane = plane;
	}

	public boolean readyForFlight() {
		plane.startEngine(Plane.ENGINE_ID_LEFT);
		plane.startEngine(Plane.ENGINE_ID_RIGHT);
		return plane.verifyAllSystems();
	}
}

Test:

@PrepareForTest(Plane.class)
public class PilotTest extends PowerMockTestCase {
	@Test
	public void testReadyForFlight() {
		Plane planeMock = PowerMockito.mock(Plane.class);
		Pilot pilot = new Pilot(planeMock);

		Mockito.when(planeMock.verifyAllSystems()).thenReturn(true);

		// testing method
		boolean actualStatus = pilot.readyForFlight();

		Assert.assertEquals(actualStatus, true);
		Mockito.verify(planeMock).startEngine(Plane.ENGINE_ID_LEFT);
		Mockito.verify(planeMock).startEngine(Plane.ENGINE_ID_RIGHT);
	}
}

Links

Source code can be downloaded from Github.

Other unusual mocking examples:

twittergoogle_plusrss