我有一个函数想要模拟:
class Base{
public:
void virtual func() { sleep(3); }
};
我的模拟看起来像:
class Mock: public Base{
public:
MOCK_METHOD(void, func, (), (override));
};
测试看起来像:
TEST(TestMockSanity, AbleToMock) {
Mock mock;
EXPECT_CALL(mock, func());
}
但是,我有 2 个问题:
- 一些愚蠢的东西- 错误:"类测试::内部::TypedExpectation<void()>"没有名为"TIMES"的成员
- 重要提示- 如何将
func
的嵌入更改为sleep(0)
?
class Real {
public:
Real(){};
virtual ~Real(){};
virtual int run();
virtual int dont_run();
};
./真实.cpp
#include "real.hpp"
int Real::run() { return 0; };
int Real::dont_run() { return 1; };
./介子.build
project(
'gtest',
'cpp',
default_options : [
'cpp_std=c++14',
],
)
sources = files('main.cpp', 'real.cpp')
executable(
'real',
sources,
install : false,
)
executable(
'mock',
files('real.cpp', 'mock.cpp'),
dependencies: [dependency('gtest'), dependency('gmock')],
install : false,
)
./模拟.cpp
#include "gmock/gmock.h" // MOCK_METHOD
#include "gtest/gtest.h" // TEST
#include "real.hpp"
class MockReal : public Real {
public:
MOCK_METHOD(int, run, (), (override));
MOCK_METHOD(int, dont_run, (), (override));
void delegate(){
ON_CALL(*this, run).WillByDefault([this](){
return 1;
});
ON_CALL(*this, dont_run).WillByDefault([this](){
return 2;
});
}
};
TEST(TestMockSanity, AbleToMock) {
MockReal mock;
EXPECT_EQ(0, mock.run());
EXPECT_EQ(1, mock.dont_run());
mock.delegate();
EXPECT_EQ(1, mock.run());
EXPECT_EQ(2, mock.dont_run());
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
./main.cpp
#include "real.hpp"
int main() {
Real r;
r.run();
return 0;
}
子项目/gtest.wrap
[wrap-file]
directory = googletest-release-1.11.0
source_url = https://github.com/google/googletest/archive/release-1.11.0.tar.gz
source_filename = gtest-1.11.0.tar.gz
source_hash = b4870bf121ff7795ba20d20bcdd8627b8e088f2d1dab299a031c1034eddc93d5
patch_filename = gtest_1.11.0-2_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.11.0-2/get_patch
patch_hash = 764530d812ac161c9eab02a8cfaec67c871fcfc5548e29fd3d488070913d4e94
[provide]
gtest = gtest_dep
gtest_main = gtest_main_dep
gmock = gmock_dep
gmock_main = gmock_main_dep
我跑完后得到:
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from TestMockSanity
[ RUN ] TestMockSanity.AbleToMock
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: run()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: dont_run()
Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
../mock.cpp:24: Failure
Expected equality of these values:
1
mock.dont_run()
Which is: 0
GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
../mock.cpp:11:
Function call: run()
Returns: 1
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
../mock.cpp:14:
Function call: dont_run()
Returns: 2
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
[ FAILED ] TestMockSanity.AbleToMock (0 ms)
[----------] 1 test from TestMockSanity (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] TestMockSanity.AbleToMock
1 FAILED TEST
当你嘲笑函数成员时,你说你会期待他们的调用。由于您尚未添加EXPECT_CALL
规则,因此MockReal
通知您有关不感兴趣的模拟调用。您可能希望明确声明允许不感兴趣的调用:
::testing::NiceMock<MockReal> mock;
模拟函数成员时
class MockReal : public Real {
public:
MOCK_METHOD(int, run, (), (override));
MOCK_METHOD(int, dont_run, (), (override));
};
它们只是覆盖基类成员:
class MockReal : public Real {
public:
int run() override {
return int{}; // Actually, some expression that evaluates to the default value int{}.
}
int dont_run() override {
return int{}; // Actually, some another expression that also evaluates to 0.
}
};
这是一个通常的虚拟方法调用 - 它们不调用父方法。如果希望它们调用父方法,通常显式调用它们:
int run() override {
return Real::run();
}
您可以使用ON_CALL().WillByDefault()
来控制默认返回表达式,它们应该在构造函数中或方法调用之前的任何位置设置,类似于上面:
MockReal() {
ON_CALL(*this, run).WillByDefault([this] { return Real::run(); });
ON_CALL(*this, dont_run).WillByDefault([this] { return Real::dont_run(); });
}
整个代码:
#include <gmock/gmock.h>
class Real {
public:
Real(){};
virtual ~Real() = default;
virtual int run();
virtual int dont_run();
};
int Real::run() { return 0; };
int Real::dont_run() { return 1; };
class MockReal : public Real {
public:
MOCK_METHOD(int, run, (), (override));
MOCK_METHOD(int, dont_run, (), (override));
MockReal() {
// Set default actions.
ON_CALL(*this, run).WillByDefault([this] { return Real::run(); });
ON_CALL(*this, dont_run).WillByDefault([this] { return Real::dont_run(); });
}
void delegate(){
// Override default actions.
ON_CALL(*this, run).WillByDefault(::testing::Return(1));
ON_CALL(*this, dont_run).WillByDefault(::testing::Return(2));
}
};
TEST(TestMockSanity, AbleToMock) {
::testing::NiceMock<MockReal> mock;
EXPECT_EQ(0, mock.run());
EXPECT_EQ(1, mock.dont_run());
mock.delegate();
EXPECT_EQ(1, mock.run());
EXPECT_EQ(2, mock.dont_run());
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
输出
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from TestMockSanity
[ RUN ] TestMockSanity.AbleToMock
[ OK ] TestMockSanity.AbleToMock (0 ms)
[----------] 1 test from TestMockSanity (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
我的 ServerMock 类中有这样的东西 这也有MOCK_METHODs
ServerMock()
{
ON_CALL(*this, Stop).WillByDefault([this] { StopImpl(); });
}
void StopImpl() const
{
...
}
希望有帮助
问题1:你必须说出你期望func()
在EXPECT_CALL
中调用的频率。例如:
EXPECT_CALL(mock, func()).Times(1);
问题 2:您可以使用 GoogletestsInvoke
对通话执行操作。