Впрыскивание через конструктор является лучшим - сохраните этот дизайн.
Но есть несколько других способов для людей, которые любят усложнять простые вещи.
1) Сделайте свой шаблон класса CLoginActivity:
template <class TaskImpl>
class CLoginActivityTemplate
{
CLoginActivityTemplate() { m_pTask = new TaskImpl(); }
};
using CLoginActivity = CLoginActivityTemplate<Task>;
В своих тестах, проверить это instantion:
using CLoginActivityTestable = CLoginActivityTemplate<TaskMock>;
Однако это не всегда так просто - потому что часто бывает трудно получить доступ к этому макету, чтобы установить расширения на нем. Но вы можете определить класс 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();
}
Вам нужно издеваться этим классом фабрики для обеспечения mock- фабрика создает макет-объект. Может быть, это не выглядит обещанием - но это только введение к следующей точке.
3) Есть специальная функция завода реализуется в другом файле:
CLoginActivity.cpp
#include "TaskCreate.hpp"
CLoginActivity::CLoginActivity()
{
m_pTask = taskCreate();
}
TaskCreate.cpp
// your "real" function here
ITask* createTask() { return new Task(); }
Имея такие дизайн- создать тест UT для CLoginActivity с использованием только выбранных файлов из ваших проектов - просто говоря - заменить TaskCreate.cpp с TaskcreateStub.cpp в вашем проекте UT:
- CloginActivity.cpp
- TaskMock. CPP (если существует)
- TaskCreateStub.cpp
TaskCreateStub.cpp должен возвращать задачу-mock - не настоящую задачу. Вам также нужен доступ к этому возвращенному макету-объекту, поэтому вы можете установить на него ожидания.
TaskCreateStub.cpp
// your "real" function here
static TaskMock* taskMockForCreateStub = nullptr;
ITask* createTask() { return taskMockForCreateStub ; }
void setTaskMockForCreateTaskStub(TaskMock* taskMock) { taskMockForCreateStub = taskMock; }
Я сильно отговорить вас от использования такого линкер уровня насмешки. Используйте его только для тестирования устаревшего кода, где вы не можете его перепроектировать, и это может быть единственным способом использования макета ...