Open lightthgil opened 3 years ago
你说的是 C 函数的mock [ 用 MOCKER(func) ] 还是 C++虚函数的mock [ 用 MOCK_METHOD(mocker, method) ]。 如果是前者,可能多个 C 函数,都是统一通过 GlobalMockObject操作的,暂时可能不好单个操作。 如果是后者,可能你针对一个mock对象 mocker,可以单独进行操作。但是一个 mocker 有多个 method 的mock,要取消其中某一个,可能没有现成的方式支持。
我还没详细去看怎么支持单个 mocker 的取消。 基于已有的特性,每个mockder 可以指定 id, 也许有可能通过 指定id的方式,取消一个 mocker。
无论是C函数使用GlobalMockObject::reset();还是C++虚函数使用mock_class_instance.reset(),最终都会调用到 https://github.com/sinojelly/mockcpp/blob/826f71bc7ba4e8bed4a1786cf4f01b6619096e55/src/ChainableMockMethodContainer.cpp#L85-L95 而resetMethod可以删除特定的mock https://github.com/sinojelly/mockcpp/blob/826f71bc7ba4e8bed4a1786cf4f01b6619096e55/src/ChainableMockMethodContainer.cpp#L71-L82 是否可以将resetMethod通过某种方式暴露出来
嗯,大概是这个思路。但是要让使用者,可以方便的 reset 指定的mocker 才行。 从你贴的代码来看, ChainableMockMethodContainerImpl::ValueType 这样的类型,用户是不好用的。
所以我说 reset 指定的 mocker, 得先有个办法指定 mocker,然后reset 它。 我能想到的是 mocker 可以指定 id, 所以如果能把 mocker 指定的 id, 与 reset 实现联系起来。 用户就可以用下面方式reset指定的mocker了。 mocker.reset(id)
老哥这个项目还在维护吗 关于reset这个。可否在一类关键字(stubs)后扩展一个reset?
老哥这个项目还在维护吗 关于reset这个。可否在一类关键字(stubs)后扩展一个reset?
你说的 .stubs之后,可以.reset 吗? 可能达不到用完一个mocker就取消的效果哦。
有需求,可以在这个issue上+1。还可以在评论中写一下具体场景,为什么需要这个特性。
当然也欢迎提出方案,甚至实现这个特性。
老哥这个项目还在维护吗 关于reset这个。可否在一类关键字(stubs)后扩展一个reset?
你说的 .stubs之后,可以.reset 吗? 可能达不到用完一个mocker就取消的效果哦。
有需求,可以在这个issue上+1。还可以在评论中写一下具体场景,为什么需要这个特性。
当然也欢迎提出方案,甚至实现这个特性。
我这边还有这个需求。 大致的应用场景是,由高级开发人员构造一个复杂的场景,模拟真实的环境,里面会有MOCK。然后低级别开发人员基于该场景去写测试用例。测试用例中可能会自己MOCK有些函数,然后自己在测试用例的结尾unmock掉。
举个栗子:
class Scenes_base : public testing::Test {
public:
Scenes_base(){};
~Scenes_base(){};
virtual void SetUp() override;
virtual void TearDown() override;
};
void Scenes_base::SetUp()
{
// do something
MOCKER(func1).stubs().will(invoke(fake_func1));
MOCKER(func2).stubs().will(returnValue(0));
}
void Scenes_base::TearDown()
{
GlobalMockObject::verify();
}
class Scenes_online : public Scenes_base {
public:
Scenes_online(){};
virtual ~Scenes_online(){};
virtual void SetUp() override;
virtual void TearDown() override;;
};
void Scenes_online::SetUp()
{
Scenes_base::SetUp();
// do something
}
void Scenes_online::TearDown()
{
Scenes_base::TearDown();
}
TEST_F(Scenes_online, return_1_offline_when_xxx)
{
MOCKER(recv_online_state).stubs().will(returnValue(false)).id("recv_online_state_return_false");
// do something
EXPECT_NE(get_online_state(), false);
MOCKER(recv_online_state).id("recv_online_state_return_false").reset(); //期望这里取消桩
}
TEST_F(Scenes_online, return_1_online_when_xxx)
{
MOCKER(recv_online_state).stubs().will(returnValue(true)).id("recv_online_state_return_true");
// do something
EXPECT_NE(get_online_state(), true);
MOCKER(recv_online_state).id("recv_online_state_return_true").reset(); //期望这里取消桩
}
实际的应用会比这个例子复杂。但是大致是这个意思,在Scenes_online的几个测试用例中,希望复用基础场景Scene_base构建的环境,测试不同的功能,每个测试可能会有MOCK,如上述两个测试用例Scenes_online.return_1_offline_when_xxx
和Scenes_online.return_1_true_when_xxx
,但是每个测试用例跑完后,需要UNMOCK掉自己测试用例中的MOCKER,防止影响下一个测试用例。如果用GlobalMockObject::verify()或者GlobalMockObject::reset(),则同时会unmock掉基础场景Scene_base中的MOCKER,导致场景不可用,所以希望能仅unmock掉自己测试用例的MOCKER
应用场景:
老哥这个项目还在维护吗 关于reset这个。可否在一类关键字(stubs)后扩展一个reset?
你说的 .stubs之后,可以.reset 吗? 可能达不到用完一个mocker就取消的效果哦。 有需求,可以在这个issue上+1。还可以在评论中写一下具体场景,为什么需要这个特性。 当然也欢迎提出方案,甚至实现这个特性。
我这边还有这个需求。 大致的应用场景是,由高级开发人员构造一个复杂的场景,模拟真实的环境,里面会有MOCK。然后低级别开发人员基于该场景去写测试用例。测试用例中可能会自己MOCK有些函数,然后自己在测试用例的结尾unmock掉。
举个栗子:
class Scenes_base : public testing::Test { public: Scenes_base(){}; ~Scenes_base(){}; virtual void SetUp() override; virtual void TearDown() override; }; void Scenes_base::SetUp() { // do something MOCKER(func1).stubs().will(invoke(fake_func1)); MOCKER(func2).stubs().will(returnValue(0)); } void Scenes_base::TearDown() { GlobalMockObject::verify(); } class Scenes_online : public Scenes_base { public: Scenes_online(){}; virtual ~Scenes_online(){}; virtual void SetUp() override; virtual void TearDown() override;; }; void Scenes_online::SetUp() { Scenes_base::SetUp(); // do something } void Scenes_online::TearDown() { Scenes_base::TearDown(); } TEST_F(Scenes_online, return_1_offline_when_xxx) { MOCKER(recv_online_state).stubs().will(returnValue(false)).id("recv_online_state_return_false"); // do something EXPECT_NE(get_online_state(), false); MOCKER(recv_online_state).id("recv_online_state_return_false").reset(); //期望这里取消桩 } TEST_F(Scenes_online, return_1_online_when_xxx) { MOCKER(recv_online_state).stubs().will(returnValue(true)).id("recv_online_state_return_true"); // do something EXPECT_NE(get_online_state(), true); MOCKER(recv_online_state).id("recv_online_state_return_true").reset(); //期望这里取消桩 }
实际的应用会比这个例子复杂。但是大致是这个意思,在Scenes_online的几个测试用例中,希望复用基础场景Scene_base构建的环境,测试不同的功能,每个测试可能会有MOCK,如上述两个测试用例
Scenes_online.return_1_offline_when_xxx
和Scenes_online.return_1_true_when_xxx
,但是每个测试用例跑完后,需要UNMOCK掉自己测试用例中的MOCKER,防止影响下一个测试用例。如果用GlobalMockObject::verify()或者GlobalMockObject::reset(),则同时会unmock掉基础场景Scene_base中的MOCKER,导致场景不可用,所以希望能仅unmock掉自己测试用例的MOCKER
看了下实列我觉得取消的桩的方式略显复杂 希望的方式如下:
TEST_F(Scenes_online, return_1_online_when_xxx)
{
MOCKER(recv_online_state).stubs().will(returnValue(true));
// do something
EXPECT_NE(get_online_state(), true);
MOCKER(recv_online_state).reset(); //期望这里取消桩
}
GlobalMockObject::verify(); 或者GlobalMockObject::reset();可以取消所有的MOCKER,但是,如果我想保留一部分MOCKER,只取消另一部分MOCKER,需要怎么做?