Home > Enterprise >  How to test a function which returns void in google test?
How to test a function which returns void in google test?

Time:12-10

I have a function which needs to be tested but it returns void.

This function may modify some global variables.

For example:

/* target_code.h */

void add_num(int n);
/* target_code.c */

#include "target_code.h"

int number = 0;

void add_num(int n) {
    number  = n;
}

(The real function I want to test is more complex than it.)

And I want to use the framework - google test for testing this function.

So maybe I need to implement a test program to test it.

/* testProgram.cpp */
include "target_code.h"

/* implement the test case for it */


But this function doesn't return anything. It just modifies a global variable.

And in my coworker's point, it's not good to extern this variable number and check the value is correct or not in this example.

The one of the bad things is, maybe we will change the variable name about number and this test program may need to rewrite again (difficult to maintain).

But without this method, I don't know how to test this function works correctly or not.

A single method I thought is implementing a function which do the similar thing with add_num, and verifying this function.

Here is a example which I thought:

/* testProgram.cpp */

int fake_number = 0;
void fake_add_num(int n) {
    fake_number  = n;
}

/* Implement the test cases */

This fake_add_num do the same thing with the real function "add_num". The different between them is I can reach this fake_number directly.

Maybe there are different methods to verify this kind of functions.

Please give me an example to do that. Thanks!!

CodePudding user response:

You should figure out what the observable behavior of this function is and test that. Everything else is implementation detail.

For example, if you have a companion to your add_num function:

void print_num() {
    std::cout << number << '\n';
}

Then the observable behavior of add_num(2) isn't "number is increased by 2", it's "The number printed by print_num() is increased by 2". That is the behavior you should test.

For example, you could write a test like this:

TEST(NumTests, AddNumReflectedInPrintNum) {    
    init_num(0);
    testing::internal::CaptureStdout();
    print_num();
    ASSERT_EQ(testing::internal::GetCapturedStdout(), "0\n";)

    add_num(10);
    testing::internal::CaptureStdout();
    print_num();
    ASSERT_EQ(testing::internal::GetCapturedStdout(), "10\n";)
}

Note that the value of number is never tested anywhere. That is an implementation detail.

CodePudding user response:

You can make an internal visible method (in some internal namespace) that tests uses it to get this global state and then you can do something like

// in header
namespace my_proj {
namespace internal {
int GetNumber() { return number; }
}
}

// in test
add_num(5);
EXPECT_EQ(expected_value, GetNumber());

One last thing, using global variables is not a recommended approach because of the issues it can introduce, so if you can avoid it, might be better.

  • Related