Vishwanath Krishnamurthi's blog

A blog on Java EE, clean code, open source and TDD

A few things to avoid while writing unit tests

with 2 comments

Long back I wrote a post on some good practices to follow while writing unit tests.  I thought I’d add one on mistakes/practices to avoid while writing unit tests.

1) Reading a configuration file:

If for writing a unit test, you access a file, then strictly speaking, it is not a unit test.

For example,

class CarTest
{
Engine engine;
// your test for engine object
}

If you created the object under test by doing,

Engine engine = new Engine();

that’s neat. Whereas if DI was used to create the ‘engine’ object, then it wouldn’t have been a unit test. (DI involves reading an external file/ scanning for annotations )

Likewise, if for test data, you retrieved the data from a file, then its not really a unit test.

the main drawback being ?

Reading files takes time. A unit test has to be really fast. Something that’s executed very often.

2) Mocking the wrong objects:

Mocking frameworks are great.  You could easily mock a ‘dao’ or a ‘service’ call and write a unit-test quickly. Mocking a ‘value-object’ like the one above is needless.

public void  AccountBalanceTest
{
@Mock AccountInfo accountInfo;
@Test
public void  debitShouldDecuctTheGivenAmount()
{
when(accountInfo.getCurrentBalance()).thenReturn(500);
Account account = new Account(accountInfo);
account.debit(100);
}
}

It turns out to be messy when a lot of such stub values are defined.

‘Value-Objects’ being easily constructible with a ‘new’ should rather be used like this:

@Test
public void  debitShouldDecuctTheGivenAmount()
{
AccountInfo accountInfo = new AccountInfo();
accountInfo.setCurrentBalance(500);
Account account = new Account(accountInfo);
account.debit(100);
}
}

This reads a lot better, doesn’t it? And when there are a lot of test data to be prepared, there’s of course the very useful builder pattern http://nat.truemesh.com/archives/000714.html

3) Ignoring the feedback

A great thing about writing tests is that you get “feedback” about your code.

For example,  if you started writing a test like this,

@Test
public void testValidateAddressShouldCheckForMandatoryPostCode()
{
Customer customer = new Customer();
Address address = new Address();
address.setPostCode("123456");
customer.setAddress(address);
Validator validator = new Validator();
validator.validateAddress(customer);
}

you should be seeing a “warning” here. You’re spending some effort constructing the object required for test,

and this “warning” should hint you that, the validateAddress() method should be refactored to take an address parameter and not a customer parameter.

It is easy to set up the object like above and get the test passing – but that’s not the point. The idea should be to take the feedback and refactor.

@Test
public void testValidateAddressShouldCheckForMandatoryPostCode()
{
Address address = new Address();
address.setPostCode("123456");
Validator validator = new Validator();
validator.validateAddress(address); // refactored method.
}

Yes, the above one was a simplified example, but hope the idea is clear.

Similarly, when a piece of code is hard to test, it is possible to overcome the pain by using some advanced mocking frameworks and finishing up the test. But “being hard to test” might be a feedback telling  you to take efforts to refactor the code and make it testable/loosely-coupled.

Here’s a great post http://martinfowler.com/articles/modernMockingTools.html that explains it.

So to put it again, “the feedback should not be ignored”

 

Good TDD resources

http://misko.hevery.com/
http://www.growing-object-oriented-software.com/
http://vimeo.com/10569751

 

About these ads

Written by Vishwanath Krishnamurthi

April 9, 2012 at 11:49 pm

Posted in Design

Tagged with , ,

2 Responses

Subscribe to comments with RSS.

  1. Nice point made vishwa.good post

    sivaramom

    April 10, 2012 at 8:25 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 120 other followers

%d bloggers like this: