简体   繁体   English

依赖注入:依赖需求字段/成员

[英]Dependency Injection: Dependency needs field/member

I have two classes A and B. Currently, B is constructed inside of A. Since I want to verify in my unit tests that A calls B's methods correctly, I want to inject B into A instead to enable mocking. 我有两个类A和B。目前,B是在A内部构造的。由于我想在单元测试中验证A正确调用B的方法,因此我想将B注入A而不是启用模拟。

The problem is: Upon construction, B needs one of A's fields as a constructor parameter. 问题是:在构造时, B需要A的字段之一作为构造函数参数。 Which means that if I inject B and therefore move its construction out of A, I would also have to move that field's construction out of A. 这意味着,如果我注入B并因此将其构造从A移出,那么我也必须将该字段的构造从A移出。

What's the most elegant solution here? 这里最优雅的解决方案是什么? I hope I explained the problem properly. 我希望我能正确解释这个问题。 If not, please feel free to ask any questions. 如果没有,请随时提出任何问题。

An attempt at explaining the problem with code snippets: 尝试解释代码片段的问题:

What it's currently like: 目前的状况:

// constructor of class A. b_ is being constructed. field_of_a_ is initialized.
A::A() : b_{field_of_a_}, field_of_a_{5} {

}

What I want to avoid: 我要避免的是:

// In the class constructing A...
int field_of_a;
B b(field_of_a);
A a(b, field_of_a);

// and inside A...
A::A(B& b, int& field_of_a) : b_{b}, field_of_a_{field_of_a} {

}

EDIT 1: Clarification from inside one of my comments: 编辑1:从我的评论之一中澄清:

Yeah so currently B holds all kinds of timers and timer related methods. 是的,因此B目前拥有各种计时器和与计时器相关的方法。 Its methods are called by A during message handling. 在消息处理期间,A调用其方法。 B needs access to a queue and a few other resources located inside of A. When testing A, I want to verify that during message handling the timers are started/stopped correctly. B需要访问队列和位于A内部的其他一些资源。在测试A时,我想验证消息处理期间计时器是否正确启动/停止。

Instead of passing B, you should pass a factory that generates B. It still maintains the dependency injection. 除了传递B之外,还应该传递一个生成B的工厂。它仍然保持依赖项注入。 The factory could be a virtual class, a function pointer, a std::function, ... 工厂可以是一个虚拟类,一个函数指针,一个std :: function等。

It is then up to A to use the factory. 然后由A决定使用工厂。 Your test would simply verify that the factory is used during construction of A. 您的测试只需验证在A的制造过程中是否使用了工厂。

Update : your factory should be abstract, and return an instance to the public interface of B that A requires. 更新:您的工厂应该是抽象的,并将实例返回到A所需的B的公共接口。 During testing the factory can be programmed to spawn mocked instances of B. 在测试过程中,可以对工厂进行编程以生成模拟的B实例。

Also, make sure that in the class definition of A the member passed to B is declared first, then the member holding a B instance. 另外,请确保在A的类定义中,首先声明传递给B的成员,然后声明拥有B实例的成员。 This in order to make the first member's lifetime outlive that of B. 这是为了使第一个成员的寿命超过B。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM