Tôi có một lớp Foo sử dụng thanh lớp. Bar chỉ được sử dụng trong Foo và Foo đang quản lý Bar, do đó tôi sử dụng unique_ptr (không phải là một tài liệu tham khảo, bởi vì tôi không cần thanh bên ngoài của Foo):Sự tiêm phụ thuộc với unique_ptr để giả lập
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_;
};
Cho đến nay rất tốt, điều này hoạt động tốt. Tuy nhiên, tôi có một vấn đề khi tôi muốn kiểm tra đơn vị mã:
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();
}
Xét nghiệm này thất bại vì đối tượng giả được chuyển fo Foo, và thiết lập một kỳ vọng vào mô hình như thất bại.
tùy chọn có thể có của DI:
- bởi shared_ptr: là quá nhiều trong trường hợp này (Bar đối tượng không được chia sẻ giữa Foo bất kỳ điều gì khác)
- bằng cách tham khảo để Ibar: không phải là một tùy chọn (Bar không được lưu trữ bên ngoài Foo, vì vậy đối tượng Bar được tạo sẽ bị hủy bỏ để lại Foo với tham chiếu lơ lửng)
- by unique_ptr: không thể kiểm tra theo cách được trình bày
- bằng cách truyền theo giá trị: không thể occure - cùng một vấn đề như với unique_ptr).
Giải pháp duy nhất tôi nhận được để lưu trữ con trỏ thô để BarMock trước Foo trở thành duy nhất chủ sở hữu của BarMock, tức là .:
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;
};
không Có một giải pháp sạch hơn? Tôi có phải sử dụng tiêm phụ thuộc tĩnh (mẫu) không?
Bạn có thể quan tâm đến việc đọc [câu trả lời này] (http://stackoverflow.com/questions/7616475/can-google-mock-a-method-with-a-smart-pointer -trên loại/11548191 # 11548191). –
@ πάντα ῥεῖ: cảm ơn bạn đã liên kết. Tôi đã nhìn thấy nó và nó hoạt động cho các phương thức lấy unique_ptr như một tham số - nhưng tôi không chắc chắn một phương pháp nào có thể áp dụng cách tiếp cận này cho các nhà xây dựng. – Quarra