这个问题不太可能帮助任何 future 的访客;它仅与一个小地理区域、一个特定时刻或一个非常狭窄的情况相关,而这些情况通常不适用于互联网的全局受众。如需帮助使这个问题更广泛地适用,visit the help center .
10年前关闭。
假设一个类(class)Foo
, 依赖 Bar
它由一些 DI 框架(在本例中为 CDI)注入(inject):
public class Foo {
@Inject
private Bar bar;
...
public void someLogic() {
...
}
}
让 - 为了这个例子 -
Bar
成为可模拟的基础设施依赖项,例如 EntityManager
或 UserTransaction
,这超出了单元测试的范围,但是 - 再次为了示例 - 需要 Foo 正确初始化。假设 单元测试
FooTest
(我明确地想编写没有容器依赖的单元测试),它需要以某种方式设置或模拟依赖,但在其他方面试图在所需的容器功能方面保持低调(因此不是集成测试)。public class FooTest {
private Foo foo;
@BeforeClass
public void initFoo() {
... set bar somehow ...
}
@Test
public doSomeTestOnSomeMethod() {
...
}
}
我试图收集一些关于什么是最佳策略的事实,以便在我的测试中设置这些原本由容器控制的依赖项:
(1) 添加
getBar()
和 setBar()
至Foo
(-) 不必要的、臃肿的代码(?)
(+) 直截了当
(+) 适用于所有(测试)类
(2) 使用反射设置
bar
(-) 复杂,难以阅读和维护
(+) 适用于所有(测试)类
(3) 删除
private
限定符以使这些字段可从测试中访问(假设相同的包)(+) 最简单、最短的解决方案
(-) 就生产代码而言,不是最小范围
(-) 不能在包装外使用
关于这个话题有什么明确的建议吗?
更新:我知道我可以将容器用作测试的依赖项提供程序——我这样做是为了进行集成测试,但我当然不希望在单元测试中使用完整的 Java EE 堆栈。
我希望这不会导致框架上的火焰战;-)
更新 2:感谢大家到目前为止的回答,但我似乎表达了自己不清楚。答案往往表明我没有充分利用底层 DI 框架的可能性,或者只是需要更多的模拟。这当然是好的和真实的,但我更想收集关于是否可以将类成员的可见性扩展到默认级别以利用可测试性,如果“测试独占”-getter-setter 方法更好,或者如果反射(我目前的解决方案)是要走的路。试图编辑问题,以便更好地描述我的问题。
恢复和关闭如果我有适当的权利,我非常想结束这个问题,因为我显然以一种非常误导和令人困惑的方式表达了自己。我既不想在测试中寻找关于正确依赖注入(inject)的讨论,也不需要任何代码片段。我的 - 光荣地失败了 - 打算开始讨论我在更新 2 中已经写的内容。感谢所有做出贡献的人 - 我一定会在 future 的问题上付出更多的努力。
最佳答案
我认为您应该更改代码,以便通过构造函数声明此依赖项,并让 DI 框架将其注入(inject)那里,然后在您的测试中通过模拟。
以目前的方式使用它会使对这个东西的依赖“隐藏”,消费代码无法知道 Bar
是必需的,这会使代码困惑且难以理解。
这也意味着您依赖于 DI 框架,而不是能够根据需要手动构建对象图。如果您愿意,看起来这可能会使更改 DI 框架变得困难
关于java - 从单元测试中设置依赖关系的最佳策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6733585/