3

I have a method that contains a static unsigned int, so it can return consecutive directory names. Something like:

string MyClass::createDirectory() const
{
    static unsigned int i = 0;
    stringstream ss;
    string directory;
    do
    {
        ++i;
        ss.str("");
        ss << "/" << setfill('0') << setw(6) << i;
        directory = m_rootDirectory + ss.str();

    } while(!m_filesystem->createDirectory((directory)));

    return directory;
}

I know this is pretty naive solution, but it is good enough for now.

But I have encountered problem while writing unit tests - the static variable is incremented between test cases.

Is there a way to reset such variable? Or is changing static method variable to non-static class member my only option?

I'm using Google Test framework.

Dino
  • 599
  • 1
  • 9
  • 20
  • 1
    A nasty hack will be using e.g. `#ifdef _TEST... #else ... #endif` to replace the static local variable with a global variable, which you can reset/change during your test. As I said, it is a nasty hack and I know this is not acceptable by many. But if your method is going to be changed but need to unit test your prototype in the time being, why not use it as a temporary hack. – simon Jul 27 '15 at 11:17

3 Answers3

5

There is no way you can reset a static local variable out of the scope of the function it is declared in.

I would try to implement your MyClass::createDirectory function without a static local, even if it requires redefining the function's signature or even the whole class' interface.

Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61
  • Anyway your method obviously has 2 responisibilities: - creating a directory - generating a name. Propably moving name generation to another class will be the best option. – gandgandi Jul 27 '15 at 10:04
  • 2
    @gandgandi Yeah, I know. This implementation will be changed soon, but I wanted to have tests in place. – Dino Jul 27 '15 at 10:08
0

While the currently accepted answer is valid, it's also possible to verify the behavior of your createDirectory() method without refactoring to remove the static variable. Since createDirectory() returns a string, it's fairly straight-forward to use regular expressions to validate directory names returned by the function. For example, if the goal is to validate that subsequent invocations of createDirectory() return directory names with sequentially incrementing sequence numbers, you can write a test which invokes createDirectory() twice. In both cases you'll capture the sequence number using a regex, and compare them to make sure that the second invocation produces a sequence number that is greater than the first. This way, you can test the functionality without depending on specific values.

If you haven't already, check out googlemock's regular expression matchers and the ASSERT_THAT() macro. Both are very useful in these cases.

Ian
  • 842
  • 5
  • 16
-3

I haven't used the googletest framework (though I wish I could).

A quick Google gives me the following information, which is directly related and should help you a lot.

If you find yourself writing two or more tests that operate on similar data, you can use a test fixture. It allows you to reuse the same configuration of objects for several different tests.

Namely, you should be setting up the object each time a test runs, in a static method you usually require a reset() or akin to remember what it should be like after every run. No need to create new instances.

Similar to jUnit's setup and teardown.

Edit: I just realised you may be asking for a different thing than what I'm going on about. Shouldn't static unsigned int i = 0; set it to 0 each run? I'm not sure if this is purpose behaviour by googletest or not.

insidesin
  • 735
  • 2
  • 8
  • 26
  • 2
    The problem here is, that static variables are not binded to objects, so event though my test object is created for each test case, the static variable is incremented on its own. – Dino Jul 27 '15 at 09:57
  • 1
    @Dino it's hard to keep up with C++ and Java at the same time hahah. [Here's a solution to your problem I think, with `googletest` aside.](http://stackoverflow.com/questions/6223355/static-variables-in-class-methods). I remember using jUnit with a static properties and my solution was to de-construct and reconstruct the object each test, or at least forcibly reset it. – insidesin Jul 27 '15 at 10:01
  • 1
    I'm aware of how static works, I just wondered if there is some kind of hack that will help me out in this case. ;) – Dino Jul 27 '15 at 10:04
  • Yeah sorry I don't mean to come across that way. I think I should just stop talking honestly :L @dino I will definitely watch this thread though as clearly I need to learn this too. – insidesin Jul 27 '15 at 10:07
  • Thanks for your reply anyway. ;) – Dino Jul 27 '15 at 10:10