Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should method preconditions be unit tested?

I use Guava's Preconditions to validate the input of my methods, e.g.:

class TestedClass {
  public double sqrt(double value) {
    Preconditions.checkArgument(value >= 0.0, "negative value: %s", value);
  }
}

I am wondering should the preconditions be unit tested? Should I have a test:

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void shouldFailWhenValueIsNegative() {
   exception.thown(IllegalArgumentException.class);
   exception.expectMessage("negative value: -1");

   new TestedClass().sqrt(-1);
} 
like image 807
Adam Siemion Avatar asked Jan 09 '15 09:01

Adam Siemion


People also ask

Should every method have a unit test?

Every behavior should be covered by a unit test, but every method doesn't need its own unit test. Many developers don't test get and set methods, because a method that does nothing but get or set an attribute value is so simple that it is considered immune to failure.

When should the unit testing be performed?

Unit testing is the first software testing phase in SDLC and it is usually taken up during the development of the application. These unit test cases are written and executed by software developers.

What Cannot be unit tested?

Any component that interacts with an external database, files, or the network cannot be checked as part of unit testing. Unit tests primarily test isolated components during the product's early development phase. Developers using frameworks like Nodejs, Angular, etc., employ Unit Testing Frameworks.

What should be tested in unit test?

A unit test is a way of testing a unit - the smallest piece of code that can be logically isolated in a system. In most programming languages, that is a function, a subroutine, a method or property. The isolated part of the definition is important.


2 Answers

My opinion is that yes, you should typically have tests that verify that the behavior of your method matches that specified by its contract (including preconditions). If you say your method throws a certain exception when given a negative value for a parameter, have a test that ensure's that's true.

For really common things like NullPointerException, guava-testlib has NullPointerTester, which we use for testing that NPE is thrown for parameters that aren't annotated with @Nullable.

like image 108
ColinD Avatar answered Sep 30 '22 19:09

ColinD


To posit the opposite argument (and sit on the fence with an 'It depends'), the how the preconditions are checked is an implementation detail, the fact is that the behaviour that you want is that an exception is thrown if the preconditions are violated. Given this I think you should check these conditions in your tests as your tests should verify that the behaviour is what you expect.

Having said that I think it depends on what the preconditions are checking, and how they are applied. If you are applying annotation to the whole package so that no null values are allowed to be passed, then it doesn't make sense to me to then check that with a test for every method.

But in your example you are checking something specific in your sqrt function and the fact that you are checking with a specific piece of technology is, IMHO, irrelevant and you should test for that to validate the behaviour of the method.

like image 41
Sam Holder Avatar answered Sep 30 '22 19:09

Sam Holder