Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to compare object in a Unit test

I'm writing unit tests for my grails application, and I realized I don't really know the proper way to assert whether an object is the proper object or not.

For example, given this test:

void testExampleTest() {
    mockSession.person = new Person(firstName:'John', lastName:'Doe', middleInitial:'E')
    def model = controller.testMethod()
    ...assertions...
}

and

def testMethod = {
    Person currPerson = session.getAttribute("person")
    render(view:'view',model:[person:currPerson]
}

how should I make sure that the person object I added to the session is properly being passed in the model? Is it sufficient to use

assertEquals( person,model['person'] )

or because I injected the object myself into the session does it make more sense to use

assertEquals( person.firstName, model['person'].firstName )
assertEquals( person.lastName, model['person'].lastName )
assertequals( person.middleName, model['person'].middleName )

It seems to me that the first way should suffice as long as the object has a properly defined equals method, but I just wanted to see what the conventional way is.

Thanks

like image 425
Mike Caputo Avatar asked Jul 13 '11 19:07

Mike Caputo


3 Answers

Property-by-property comparison needs to be repeated in every test - so it's a good old code duplication, a test smell described in XUnitPatterns. Better have a proper equals().

Of course, you can add an utility method personEquals() or even override Person.equals() in runtime. For mocked class, you will probably have to. I personally stick to shorter code which is just one assertEquals() when possible.

like image 159
Victor Sergienko Avatar answered Oct 06 '22 00:10

Victor Sergienko


Funny, I and a colleague had a similar discussion today. Our conclusion was that

An advantage of the more laborious attribute-by-attribute comparison is that it reports a specific difference rather than just a "no, they are not equals", and this may be convenient.

Also we did not have control over certain classes, and some of those lacked an equals method.

We intend to investigate whether it's possible to use reflection to implement a comparator, hence removing some of the tedium.

like image 28
djna Avatar answered Oct 06 '22 00:10

djna


I have found that doing property by property is a little more reliable and gives you a little bit more fine grain control over how something is compared, the down side is it's a little more work to set up and maintain

like image 40
Bob The Janitor Avatar answered Oct 06 '22 01:10

Bob The Janitor