I am writing unit tests for a fairly simple function that depends on a fairly complicated set of data. Essentially, the object I am manipulating represents a graph and this function determines whether to chart a line, bar, or pie chart based on the data that came back from the server.

My question is, should I use mock data that is procured from the actual database? Or can I just fabricate data that fits the different cases?

I'm afraid that fabricating data will not expose bugs arising from changes in the database, but on the other hand, it would require a lot more effort to keep the test data up-to-date that I'm not sure is necessary.

In terms of readability for the sample code, is var prop1 = graphObject.properties.key; a variable that stores a magic number that denotes the graph type? In case this is different in production already, consider a more descriptive variable name and the use of an enum rather than a magic number.
–
StuperUserMar 27 '12 at 16:19

4 Answers
4

If you already have data that you can anonymise, using it that will be quicker than chasing down a BA (Business Analyst) to review your test data to make sure that you have appropriate coverage.

I'm afraid that fabricating data will not expose bugs arising from changes in the database

That's not the point of unit testing, if your tests depend on LIVE data, then it's an integration test.

For your unit tests, get a snapshot of data that covers ALL situations (or as many as possible that already exist) from the database and use that for your unit tests, and fabricate any edge cases with the help of a BA.

If your requirements don't change, your tests won't get out of date. If your requirements do change, you'd need to update the tests anyway.

You shouldn't be testing the code that brings the data to the browser in the same test as the code that builds your bar/line/pie chart. You should make it easy to supply the data to your chart building code and easily test it. This will also provide you with good separation of concerns AND make your tests run faster by simply taking mocked data rather than the results of a database read.

Ensure that tests are easy to write, fast to run, and have clear intent (short). Part of clear intent means it's better to show the mocked data your test is using rather than relying on a blackbox of data that another developer will have to run SQL/read an outside file to see.

Indeed, test isolation is important in making unit tests useful as real unit tests. Hybrid tests tend to slow down and even break. I've seen developers be put off using automated tests for this reason.
–
StuperUserMar 27 '12 at 16:21

For a real unit test the data should describe the happy path as well as edge cases and malformed data. Figure out how the data would look like for the average case (happy path). If it works with that, try to think of data that is on the edges like no data at all or data that is exactly as long as your columns permit (edge cases). At last check if the code wirks with data that does not look like you would normally expect it, e.g. if you store a phone number as a string serve your object a phone number that contains letters (malformed data).