Google Test and static local variable
我有一个包含static unsigned int的方法,因此它可以返回连续的目录名。类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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;
} |
我知道这是一个非常幼稚的解决方案,但现在已经足够好了。
但是我在编写单元测试时遇到了问题——静态变量在测试用例之间递增。
有没有办法重置这样的变量?或者将静态方法变量更改为非静态类成员是我唯一的选择?
我正在使用谷歌测试框架。
- 恶意黑客将使用#ifdef _TEST... #else ... #endif将静态局部变量替换为全局变量,您可以在测试期间重置/更改该变量。正如我所说,这是一个讨厌的黑客,我知道这是不可接受的许多。但是如果你的方法将要改变,但需要在目前对你的原型进行单元测试,为什么不把它当作一个临时的黑客。
无法将静态局部变量重置为超出其声明的函数范围。
我将尝试在没有静态局部的情况下实现您的MyClass::createDirectory函数,即使它需要重新定义函数的签名,甚至整个类的接口。
- 无论如何,您的方法显然有两个责任:-创建一个目录-生成一个名称。将名称生成移动到另一个类是最好的选择。
- @甘甘迪是的,我知道。这个实现很快就会改变,但我希望有适当的测试。
虽然当前接受的答案是有效的,但也可以在不重构以删除静态变量的情况下验证createDirectory()方法的行为。由于createDirectory()返回一个字符串,所以使用正则表达式来验证函数返回的目录名是相当直接的。例如,如果目的是验证随后调用createDirectory()返回的目录名是否按顺序递增序列号,则可以编写一个调用createDirectory()两次的测试。在这两种情况下,您都将使用regex捕获序列号,并对它们进行比较,以确保第二次调用生成的序列号大于第一次调用的序列号。这样,您就可以在不依赖特定值的情况下测试功能。
如果还没有,请查看GoogleMock的正则表达式matchers和ASSERT_THAT()宏。在这些情况下,两者都非常有用。
我没有使用googletest框架(尽管我希望可以)。
一个快速的谷歌给了我以下的信息,这是直接相关的,应该会帮助你很多。
如果您发现自己编写了两个或多个对类似数据进行操作的测试,那么可以使用一个测试夹具。它允许您为几个不同的测试重用相同的对象配置。
也就是说,您应该在每次测试运行时设置对象,在静态方法中,您通常需要reset()或类似的东西来记住每次运行后应该是什么样子。不需要创建新实例。
类似于Junit的设置和拆卸。
编辑:我刚刚意识到你可能要求的是一件不同于我所要做的事情。难道static unsigned int i = 0;不应该设置为每次运行0吗?我不确定这是否是googletest的目的行为。
- 这里的问题是,静态变量没有绑定到对象,因此尽管我的测试对象是为每个测试用例创建的,但是静态变量本身是递增的。
- Dino很难跟上C++和Java的同时,哈哈。我想这是解决你问题的办法,把googletest放在一边。我记得在静态属性中使用JUnit,我的解决方案是在每个测试中对对象进行解构和重构,或者至少强制重置它。
- 我知道静态是如何工作的,我只是想知道在这种情况下是否有某种黑客可以帮助我。;)
- 是的,对不起,我不是有意这么做的。我想我应该停止诚实地说:我@迪诺我肯定会看这条线,尽管很明显我也需要学习它。
- 不管怎样,谢谢你的答复。;)
- 我羡慕那些在C++中工作的人。@迪诺