【问题标题】:Mocking a bean in a Spring context在 Spring 上下文中模拟 bean
【发布时间】:2018-08-07 10:44:58
【问题描述】:

我想测试一个Spring beanA,当然这个bean是a的一部分
context 并且它使用其他 bean 来执行操作。

在我想为这个测试模拟的上下文中有一个特定的 bean B,并注意 B 没有注入到 A (我可以使用@InjectMocks@Mock 注释轻松处理这种情况),B 被注入到 C 被注入到 D ,即注入到A

我可以在测试 A 类时只模拟 B 吗? 你怎么能做到这一点?

【问题讨论】:

  • 你为什么要这样做?如果 A 不直接使用 B,则没有理由嘲笑它。看起来你只需要模拟 D。
  • 你试过@MockBean吗?
  • @dehasi 不使用 SpringBoot

标签: java spring mocking mockito


【解决方案1】:

假设测试类用@RunWith(MockitoJUnitRunner.class)注解,你可以试试这个:

@Mock
private B b;

@InjectMocks
@Spy
private C c = new C();

@InjectMocks
@Spy
private D d = new D();

@InjectMocks
private A a = new A();

快速解释:B 将被嘲笑。 C 和 D 将使用 new 创建(这里没有模拟,所以我们用@Spy 标记)。 @InjectMocks 将在 C 中注入 B,在 D 中注入 C,在 A 中注入 D。希望它有所帮助。我的这段代码(只是一个示例应用程序代码)here 中提供了一个更完整的示例。注意真实对象和模拟对象是如何注入到同一个类中的。

如果你使用SpringRunner,另一种方法是:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {A.class, Bmock.class, C.class, D.class})

其中Bmock.class 是您已经在项目中某处创建的模拟。这种方法还假设您正确分离了接口和实现:只有当您在 D 中自动装配 B 接口而不是 B 具体类时,它才会起作用。

【讨论】:

  • 哦,是的,有道理,只有一件事,我们为什么需要间谍?
  • Spy 告诉 Mockito 不要模拟该对象,而仅在它出现时使用它。
  • 是的,这也是有道理的,但是我们可以使用 Spring @Autowired 完成类似的事情吗,因为我正在使用 Spring runner 进行测试?
  • 仅当您使用 SpringRunner 或 SpringBootIntegrationTest。在我发布的代码中,我假设 runner 是 MockitoJUnitRunner,所以它需要知道如何注入对象。
  • 不,我正在使用 SpringRUNner,所以我有一个上下文,我只想模拟这个上下文的一个 bean,有没有办法?感谢您的宝贵时间
【解决方案2】:

这就是你的依赖的样子 -

B -> C -> D -> A

既然你想测试 Bean A,你唯一想模拟的是 D 并且不应该关心 D 需要什么。 Mockito 将为您完成这项工作。

如果为了测试A,你想模拟BC 等所有依赖项,那么你做错了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 2013-03-12
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    相关资源
    最近更新 更多