Dependency injection with unique_ptr to mock(使用 unique_ptr 进行依赖注入来模拟)
问题描述
我有一个使用类 Bar 的 Foo 类.Bar 只在 Foo 中使用,Foo 正在管理 Bar,因此我使用 unique_ptr(不是参考,因为我不需要 Foo 之外的 Bar):
I have a class Foo that uses class Bar. Bar is used only in Foo and Foo is managing Bar, therefore I use unique_ptr (not a reference, because I don't need Bar outside of Foo):
using namespace std;
struct IBar {
virtual ~IBar() = default;
virtual void DoSth() = 0;
};
struct Bar : public IBar {
void DoSth() override { cout <<"Bar is doing sth" << endl;};
};
struct Foo {
Foo(unique_ptr<IBar> bar) : bar_(std::move(bar)) {}
void DoIt() {
bar_->DoSth();
}
private:
unique_ptr<IBar> bar_;
};
到目前为止一切顺利,这工作正常.但是,当我想对代码进行单元测试时遇到了问题:
So far so good, this works fine. However, I have a problem when I want to unit test the code:
namespace {
struct BarMock : public IBar {
MOCK_METHOD0(DoSth, void());
};
}
struct FooTest : public Test {
FooTest() : barMock{ make_unique<BarMock>() }, out(std::move(barMock)) {}
unique_ptr<BarMock> barMock;
Foo out;
};
TEST_F(FooTest, shouldDoItWhenDoSth) {
EXPECT_CALL(*barMock, DoSth());
out.DoIt();
}
测试失败,因为模拟对象是为 Foo 传输的,并且对此类模拟设置期望失败.
The test fails because the mock object was transfered fo Foo, and setting an expectation on such mock fails.
DI 的可能选项:
- by shared_ptr:在这种情况下太多了(Bar 对象不会在 Foo 之间共享任何其他东西)
- 通过引用 IBar:不是一个选项(Bar 不存储在 Foo 之外,因此创建的 Bar 对象将被破坏,留下 Foo 的悬空引用)
- by unique_ptr:无法以所提供的方式进行测试
- 通过值传递:不可能(会发生复制 - 与 unique_ptr 相同的问题).
我得到的唯一解决方案是在 Foo 成为 BarMock 的唯一所有者之前存储指向 BarMock 的原始指针,即:
The only solution I got is to store raw pointer to BarMock before Foo become solely owner of BarMock, i.e.:
struct FooTest : public Test {
FooTest() : barMock{new BarMock} {
auto ptr = unique_ptr<BarMock>(barMock);
out.reset(new Foo(std::move(ptr)));
}
BarMock* barMock;
unique_ptr<Foo> out;
};
没有更干净的解决方案吗?我是否必须使用静态依赖注入(模板)?
Isn't there a cleaner solution? Do I have to use static dependency injection (templates)?
推荐答案
毕竟,我最终在任何地方都使用了这种方法:
After all, I ended up using this approach everywhere:
struct FooTest : public Test {
FooTest() : barMock{new BarMock} {
auto ptr = unique_ptr<BarMock>(barMock);
out.reset(new Foo(std::move(ptr)));
}
BarMock* barMock;
unique_ptr<Foo> out;
};
它与 gtest/gmock
一起工作得很好.
and it works fine with gtest/gmock
.
这篇关于使用 unique_ptr 进行依赖注入来模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 unique_ptr 进行依赖注入来模拟
基础教程推荐
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 设计字符串本地化的最佳方法 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01