0

I am doing unit testing in c++ using cppunit. I have seen some examples over internet that are showing testing a function that return some value. I have some functions in my project that do not return any value but do some calculations inside. Here I want to test the calculations inside those functions whether calculations are being done correctly or not, how can I do it? For example I have a function

void Flash::SerializeToBytes(Buffer &buffer) const
{
    // calculations
} 
Umair Jameel
  • 1,573
  • 3
  • 29
  • 54

2 Answers2

3

The general concept of these automatic tests is always the same: you know that, given a certain input, a function should yield a certain result. Compare the actual result with the one you expect. If they are the same, the test is passed, otherwise you either have a bug in your code or in your test.

That said, let's try to apply it to your specific case. You are passing buffer by reference, so that you can modify it (otherwise it should be a const reference!). So you have to write tests that call your function and then check what happened to buffer, instead of checking the returned value. Conceptually it's the same: you provide some input and compare the output with the expected one. It's just that in this case the output isn't a returned value, but rather the same object used as input.

In case this is not possible, for example because the arguments are passed by const reference or by value, you must understand how your function interacts with the rest of the world. If it doesn't return, throw, modify one of the input arguments, etc, then it is not a good candidate for these tests. These could mean 2 things: that it is a function you don't care about testing (at least in this way), or that you must refactor your code.

An example of the former would be something that interacts with hardware. Suppose you are writing code for some embedded system with a LED, and you have a function to turn the LED on or off. This is not a case that lends itself to automatic tests. Just skip it, you don't need to cover 100% of your code with automatic tests (see this great answer).

On the other hand, maybe your function interacts with the rest of the world thanks to global variables, which your program makes heavy use of (terrible idea). Well in this case you could still write some tests (just check what happens to the global variables after you have called the function), but what you should do is refactoring your code so that your function receives as argument all the variables that it needs, and after you've done it for all the functions, you can change the global variables to non-global, and you end up with functions that return a value and/or modify the arguments passed as reference or pointer, for which writing tests is easy.

To make it short: if you have a function that you don't know how to test, then probably either writing tests for it isn't worth it, or it is an indicator that your code might require some changes.

Community
  • 1
  • 1
  • Yes, this is a good idea. Thank you for the suggestion. But what if I don't pass by reference because I have some function that take value not by reference. – Umair Jameel Aug 28 '15 at 10:09
  • @UmairJameel I was going to reply here in the comments, but it would have been too long, so I have updated my answer, now it also covers this question. – Fabio says Reinstate Monica Aug 28 '15 at 23:04
1

If a function has no return it can still have side effects. For example, the object's state changes (such as a member variable/field). In your case it looks like the argument passed by reference (Buffer) may be modified. You can test against that.

Generally, you need to test the effects of a method that returns void, such as:

  • Does it change an object's state?
  • Can it throw exceptions?
  • Does it modify the arguments passed?
  • What does it do with different argument values/states?

If the calculations in your example are complex you may want to break up the method so that it the logic sits in another class (e.g. a calculation class). In this class it can have a single or number of public methods you can test against.

Class Skeleton
  • 2,913
  • 6
  • 31
  • 51
  • Actually the project I have started working on (in a team) that contain more than 200 classes and all classes are using other's functions so I can't change behavior of any function. – Umair Jameel Aug 28 '15 at 10:14
  • In that case the four questions I have listed should be more than enough to construct unit tests. – Class Skeleton Aug 28 '15 at 10:27