Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test helper methods?

I have classes which previously had massive methods so I subdivided the work of this method into 'helper' methods.

These helper methods are declared private to enforce encapsulation - however I want to unit test the big public methods. Is it good to unit test the helper methods too as if one of them fail the public method that calls it will also fail, and this way we can identify why it failed?

Also in order to test these using a mock object I would need to change their visibility from private to protected, is this desirable?

like image 936
Aly Avatar asked Dec 07 '09 17:12

Aly


People also ask

Should helper methods be unit tested?

Should testing helper classes be unit tested? Not directly. Helper classes only should exist as product of refactoring of unit tests for readability. Hence, just as regular unit tests, they should not be unit tested.

What techniques are used in 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 test helpers?

Testing helpers follows previous patterns shown in Testing Components, because helpers are rendered to templates just like components. Helpers are best tested with rendering tests, but can also be tested with unit tests.

What are the three A's of unit testing?

The idea is to develop a unit test by following these 3 simple steps: Arrange – setup the testing objects and prepare the prerequisites for your test. Act – perform the actual work of the test. Assert – verify the result.


3 Answers

One way is to omit private and put the tests in the same package. Then the tests can call the internal methods but no one else (= outside the package) can.

Also, failing internal methods should produce error messages which make it easy to fix the issue. When you put the code into production, you'll see less than the tests and you'll be under a lot of pressure to fix the issues fast. So one minute spent here will save you one hour later with your boss sitting in your neck.

like image 123
Aaron Digulla Avatar answered Oct 17 '22 13:10

Aaron Digulla


This smells like you have the wrong problem. What you've described is akin to creating a sub-"unit test", which leads me to believe that your unit tests are really testing a unit after all.

Which is not a criticism of what you are trying to do: going from "where we are today" to "somewhere else that's measurably better" is a winning move. However, it is a suggestion that you step back a bit to evaluate where you are - understanding how your current situation differs from some Platonic ideal could help to show new possibilities.

There are plenty of suggestions here about scoping your helper methods. Another possibility would be to review the implementation to determine if there are helper classes lurking in your current implementation. Creating a new class and a suite of tests to exercise it is always acceptable.

Note that this approach insulates you from the refactoring: you can change the implementation without changing your test suite (because the unit tests for the helper object continue to pass even when the helper object is no longer part of your production implementation), and you get a clean packaging of the implementation and the tests for it (usecase: you decide that bozo-sort is the wrong implementation, and should no longer be used. If the bozo-sort implementation is isolated, then you simply remove it and its tests. But when the tests of the bozo-sort implementation are tangled with all of the other tests, there's more thinking involved).

It may also help to review why you have unit tests for your code. If one of the reasons is "to make refactoring safe", then you don't want to be writing tests that lock you into an implementation.

like image 28
VoiceOfUnreason Avatar answered Oct 17 '22 13:10

VoiceOfUnreason


If your class really is that big, then it sounds like you should be breaking out helper objects, not just helper methods (although extracting methods is often a step along the way). Once you've done that, your old class becomes simpler and easier to test (perhaps with mocks, perhaps not), and you can test the methods on the new supporting classes directly.

My preference is to test through the public API of an object. If that's too hard, then it's a hint that the object should be broken up.

like image 37
Steve Freeman Avatar answered Oct 17 '22 15:10

Steve Freeman