如何注入模拟对象
How to inject mock object?
我正在尝试做一个单元测试来测试DoLogin方法:
CLoginActivity::CLoginActivity()
{
m_pTask = new Task();
}
void CLoginActivity::DoLogin()
{
m_pTask.execute();
}
,其中Task是我需要模拟的另一个类。
class MockTask : public Task
{
public:
MOCK_METHOD0(Execute, void());
};
要注入MockTask task
对象,我必须改变构造:
CLoginActivity::CLoginActivity(Task& task)
{
m_pTask = task;
}
或者写一个set函数:
CLoginActivity::SetTask(Task& task)
{
m_pTask = task;
}
是否有其他方法来注入代替这两个方法?我在单元测试项目中使用gmock。
通过构造函数注入是最好的——保持这种设计。
但是对于那些喜欢把简单的事情复杂化的人来说,几乎没有其他的方法。
1)制作你的CLoginActivity类模板:template <class TaskImpl>
class CLoginActivityTemplate
{
CLoginActivityTemplate() { m_pTask = new TaskImpl(); }
};
using CLoginActivity = CLoginActivityTemplate<Task>;
在你的测试中,测试这个实例:
using CLoginActivityTestable = CLoginActivityTemplate<TaskMock>;
然而,这并不总是那么容易——因为通常很难访问这个mock来设置开销。但是您可以定义TestMockWrapper类要确保访问模拟任务很容易:
class TestMockWrapper : public TestMock
{
public:
static TestMock* lastCreated;
TestMockWrapper() { lastCreated = this; }
};
using CLoginActivityTestable = CLoginActivityTemplate<TaskMockWrapper>;
2)向构造函数注入工厂对象:
CLoginActivity::CLoginActivity(ITaskFactory& taskFactory)
{
m_pTask = taskFactory.create();
}
您需要模拟这个工厂类以确保模拟工厂创建模拟对象。也许它看起来不太有希望,但这只是下一点的介绍。
3)在其他文件中实现特殊的工厂功能:
CLoginActivity.cpp
#include "TaskCreate.hpp"
CLoginActivity::CLoginActivity()
{
m_pTask = taskCreate();
}
TaskCreate.cpp
// your "real" function here
ITask* createTask() { return new Task(); }
有了这样的设计-为你的CLoginActivity创建UT测试,只使用你项目中的选定文件-简单地说-在你的UT项目中用TaskcreateStub.cpp替换TaskCreate.cpp:
- CloginActivity.cpp
- TaskMock.cpp(如果存在)
- TaskCreateStub.cpp
TaskCreateStub.cpp应该返回task-mock -而不是真正的task。您还需要访问这个返回的mock对象——这样您就可以对它设置期望。
TaskCreateStub.cpp
// your "real" function here
static TaskMock* taskMockForCreateStub = nullptr;
ITask* createTask() { return taskMockForCreateStub ; }
void setTaskMockForCreateTaskStub(TaskMock* taskMock) { taskMockForCreateStub = taskMock; }
我强烈建议您不要使用这种链接器级别的mock。仅用于测试无法重新设计的遗留代码,这可能是使用mock的唯一方法。
相关文章:
- 为什么谷歌测试/模拟显示 std::unique_ptr 泄露的模拟对象错误?
- 是否可以使用 EXPECT_CALL 来验证模拟对象的构造函数是否在某些时候调用成员函数?
- 模拟对象与模拟提升::测试
- 期望在模拟对象上调用了某个方法.它会破坏封装吗?
- 仔细阅读模拟对象的期望
- gmock-模拟对象及其内部模拟方法
- 在C 中将模拟对象施加到其抽象基类
- 模拟对象 c++
- 如何使模拟对象在Google模拟中抛出一个例外
- 将模拟对象分配给受保护的成员
- 谷歌模拟全局模拟对象内存泄漏
- 为了模拟对象,我们是否应该声明所有成员函数 virtual(C++)
- 如何将模拟对象与智能指针一起使用
- 泄露的谷歌模拟对象不会失败
- 我可以复制一个谷歌模拟对象后设置期望
- 如何生成在被测试类中创建的模拟对象
- 如何注入模拟对象
- Google Mock:在程序出口处发现泄漏的模拟对象
- GMock将一个模拟对象传递给另一个对象,并调用一个stubed方法,这仍然是在调用真正的逻辑
- 单元测试——不直接使用被模拟对象的Google Mock (c++)