Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

This is a simplified version, using jQuery:

setDefaultChartType: function (graphObject) {
  var prop1 = graphObject.properties.key;
  var numCols = 0;
  $.each(graphObject.columns, function (colIndex, column) {
    numCols++;
  });

  if ( numCols > 6 || ( prop1 > 1 && graphObject.data.length == 1) ) {
    graphObject.setChartType("line");
  } else if ( numCols <=6 && prop1 == 1 ) {
    graphObject.setChartType("bar");
  } else if ( numCols <=6 && prop1 > 1 ) {
    graphObject.setChartType("pie");
  }
}

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.

share|improve this question
    
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. –  StuperUser Mar 27 '12 at 16:19

4 Answers 4

up vote 6 down vote accepted

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.

share|improve this answer

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.

share|improve this answer
    
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. –  StuperUser Mar 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).

share|improve this answer

I think this kind of issue falls on the broad yet uncomfortable boundary between unit testing and acceptance testing. If you can specify correct behaviour without real data, then go for it.

But a lot of real requirements (or refinements to requirements) often only emerge once real data rear their ugly malformed heads, e.g:

"Oh, you mean that field uses single quotes (except when it uses double quotes)?"

"Oh, you can get negative values there, even though that makes no sense?"

"Oh, you mean that value can exceed Integer.MAX_VALUE? Nobody said..."

and so on...

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.