使用 Google 测试检查对 class 方法的调用
Check invocation of class methods using Google Test
使用 google 测试,如果我调用另一个 class 方法,我想检查是否调用了某些 class 方法。
#include "gtest/gtest.h"
class Foo {
void DoWorkPrivate(int i) {}
public:
void DoWork(int i) {}
void Run() {
for (int i = 1; i <= 5; i++) {
DoWork(i);
DoWorkPrivate(i);
}
}
};
TEST(FooTest, Run) {
Foo foo;
foo.Run(); // Need to check that DoWork() and DoWorkPrivate() are invoked
}
问题:
如何检查 DoWork()
和 DoWorkPrivate()
使用某些参数 (1, 2, 3, 4, 5) 被调用了 5 次?
How to check that DoWork() and DoWorkPrivate() are invoked 5 times with certain parameters (1, 2, 3, 4, 5)?
我能想到的是:
介绍一个副作用。让他们增加全局变量的值,或者让他们向文件写入一些东西。您可以通过跟踪副作用来衡量它们被调用的次数。
让他们递增您传递给函数的变量的值。您可以通过跟踪传递给它们的变量的变化来衡量它们被调用的次数。
PS可能还有其他我不知道的机制。
这种情况下的正常方法是创建一个 Mock-Object。有很多关于模拟和不同类型模拟的文献和文章。所以我不会在这里深入细节。例如fowler about mocking.
但一般你可以subclass class(或者通常是class的接口),你期望的方法调用。
对于您的示例,这意味着:
class FooMock : public Foo {
public:
bool isDoWorkPrivateCalled() {
return isDoWorkPrivatecall;
}
private:
DoWorkPrivate(int i) { isDoWorkPrivatecall = true;}
bool isDoWorkPrivatecall = false;
}
TEST(FooTest, Run) {
Foo *foo = new FooMocK();
foo->Run();
EXPECT_TRUE(foo->isDoWorkPrivateCalled());
}
是的,这意味着必须保护私有方法。
至少我建议使用gmock。模拟框架使用模拟功能扩展了 gtest。使用 gmock 你可以模拟一个方法
MOCK_METHOD1(DoWorkPrivate, void(int i));
然后在您的特定情况下,测试将如下所示:
EXPECT_CALL(foo, DoWorkPrivate(1)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(2)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(3)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(4)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(5)).Times(1);
使用 google 测试,如果我调用另一个 class 方法,我想检查是否调用了某些 class 方法。
#include "gtest/gtest.h"
class Foo {
void DoWorkPrivate(int i) {}
public:
void DoWork(int i) {}
void Run() {
for (int i = 1; i <= 5; i++) {
DoWork(i);
DoWorkPrivate(i);
}
}
};
TEST(FooTest, Run) {
Foo foo;
foo.Run(); // Need to check that DoWork() and DoWorkPrivate() are invoked
}
问题:
如何检查 DoWork()
和 DoWorkPrivate()
使用某些参数 (1, 2, 3, 4, 5) 被调用了 5 次?
How to check that DoWork() and DoWorkPrivate() are invoked 5 times with certain parameters (1, 2, 3, 4, 5)?
我能想到的是:
介绍一个副作用。让他们增加全局变量的值,或者让他们向文件写入一些东西。您可以通过跟踪副作用来衡量它们被调用的次数。
让他们递增您传递给函数的变量的值。您可以通过跟踪传递给它们的变量的变化来衡量它们被调用的次数。
PS可能还有其他我不知道的机制。
这种情况下的正常方法是创建一个 Mock-Object。有很多关于模拟和不同类型模拟的文献和文章。所以我不会在这里深入细节。例如fowler about mocking.
但一般你可以subclass class(或者通常是class的接口),你期望的方法调用。
对于您的示例,这意味着:
class FooMock : public Foo {
public:
bool isDoWorkPrivateCalled() {
return isDoWorkPrivatecall;
}
private:
DoWorkPrivate(int i) { isDoWorkPrivatecall = true;}
bool isDoWorkPrivatecall = false;
}
TEST(FooTest, Run) {
Foo *foo = new FooMocK();
foo->Run();
EXPECT_TRUE(foo->isDoWorkPrivateCalled());
}
是的,这意味着必须保护私有方法。
至少我建议使用gmock。模拟框架使用模拟功能扩展了 gtest。使用 gmock 你可以模拟一个方法
MOCK_METHOD1(DoWorkPrivate, void(int i));
然后在您的特定情况下,测试将如下所示:
EXPECT_CALL(foo, DoWorkPrivate(1)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(2)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(3)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(4)).Times(1);
EXPECT_CALL(foo, DoWorkPrivate(5)).Times(1);