Question

I'm trying to get my head around a clean and elegant way to keep test data that populates the mock objects. I know some tests are very specify to the data, i.e. some algorithm that assigns companies to audit based on the auditor's preferences.

Usually on my arrange, I'd setup the mocks with my fake test data, on the act I'd call the assignment service and on my assert I'd make sure the right company got assigned.

What are the best practices on where to keep and reuse test data? when do I really need to hard code data?

Was it helpful?

Solution 2

As Andrew says, normally the TestDataBuilder/TestObjectBuilder patterns are probably the cleanest way to do this, especially when dealing with integration tests. Anything else (csvs, databases etc...) introduce an extra level of indirection.

However, if you're in the .Net world I would strongly urge you to take a look at AutoFixture which automates these patterns (and a whole lot more), and in many cases can auto generate your test data for you. For example here's a snippet:

var fixture = new Fixture();
var expectedUsers = fixture.CreateMany<User>(3);

This generates 3 users with pseudorandom values automatically based on pre-defined or customizable algorithms.

Using AutoFixture, for the majority of tests, you no longer need to worry about the contents of the test data, you can just use the auto generated test data it provides you.

If your not in the .Net world, there may be similar frameworks available for test data generation.

OTHER TIPS

What you need to remember with unit testing is that you want to test a single unit of work (generally a single method) in isolation (it's dependencies have been mocked/stubbed so they don't impact on the logic in the method under test). That's where your mock objects come into play. Note your mocks generally won't need to return a massive amount of data, you will just want to return a minimal expected result to ensure that the mocked dependency does not have an unexpected influence on your method under test. Large setups (arrange) in a unit test are considered a code smell. You should consider the design of your code in this case.

Having said that one way to reduce this setup code is to use the test data builder pattern. Here is a link to an article on the "Test Data Builder".

A number of testing frameworks allow a test setup and teardown. I tend to avoid using a setup method as this makes test harder to read and understand.

Also, a colleague of mine is writing a series of blogs on TDD. He has over a decade worth of TDD experience and his blog posts are very clear and insightful. You can check them out here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top