Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beginner Unit Testing - testing complex inputs to methods

Tags:

unit-testing

I am learning to Unit Test and struggling with some probably pretty basic concepts. Let's say I have two methods.

Method A takes a file as input and returns a complex object hierarchy.

Method B takes the object hierarchy and does something with it.

I understand how to test Method A (and the various other methods that it calls in turn). I am confused with how to best test Method B.

I can build up a fake object heirarchy in my unit test to be the input to Method B but when I do this it feels like my unit test has become less of a test on Method B and more of a test of whether I manually created a valid object heirarchy correctly.

It would seem more logical to me to test Method A, keep the output and then use that to test Method B but I understand that each unit test is only meant to test one thing.

I (think) I understand the concept of mocking and faking, but I'm not sure that is the answer here as Method B is going to use the whole object heirarchy not just look at a small part of it.

like image 784
Plessiez Avatar asked May 16 '11 01:05

Plessiez


People also ask

How complex should unit tests be?

The general rule for unit tests is to test the smallest possible piece that you can test. A good rule is that each test should exercise exactly a single method from a public API. That means it should only execute this method and no other, not even transiently.

Which method is used for unit testing?

Unit Testing Techniques:Black Box Testing - Using which the user interface, input and output are tested. White Box Testing - used to test each one of those functions behaviour is tested. Gray Box Testing - Used to execute tests, risks and assessment methods.

What are the three essential A's related to unit testing?

The AAA (Arrange-Act-Assert) pattern has become almost a standard across the industry. It suggests that you should divide your test method into three sections: arrange, act and assert.


1 Answers

A strict unit test tests something in isolation. So if its a unit test, you should test in isolation. You can also have integration tests that test methodA and methodB together. I personally would start with a base unit test that tests in isolation, especially if methodB is non-trivial or mission critical. When you test in isolation you reduce the possibility that something about the test itself is causing a pass, when a test in isolation would reveal a failure.

There are cases where it is impractical to test in isolation. There are also cases where two methods are so trivial that I would test them together, like setters/getters. However this does not seem like one of them because you are complaining primarily about creating the test data.

To ease the pain of data creation for unit test, I often build a TestUtil class(es) with static (in Java-land) methods on it that return data for tests, and then I test the TestUtil. That way I only go thru the pain of doing tedious object building once, and I'm confident it's correct. In your case, since you have tested the file generation code, I would take its output and put it in one of these utility methods, and then use the utility method to test methodB in isolation.

Finally, if methodB takes a complex input, and does its work on the entire input, and its complicated, it might be that methodB is too complicated itself and should be broken down into smaller, more manageable and testable methods.

One of the primary benefits of unit/integration testing is it informs application design. If it's hard to test, its probably too complicated...

EDIT -- from your clarification, it sounds like methodB is quite complicated. Definitely test the methods that B calls in isolation; the only time I would not do that is if all the methods are private and cant be tested in isolation.

like image 187
hvgotcodes Avatar answered Sep 20 '22 08:09

hvgotcodes