如何改变模拟函数行为?



我有一个函数想要模拟:

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 个问题:

  1. 一些愚蠢的东西- 错误:"类测试::内部::TypedExpectation<void()>"没有名为"TIMES"的成员
  2. 重要提示- 如何将func的嵌入更改为sleep(0)
>./real.hpp
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对通话执行操作。

相关内容

  • 没有找到相关文章

最新更新