gpt4 book ai didi

java - @ReplaceWithMock 与 @Qualifier

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:32:22 25 4
gpt4 key购买 nike

我正在使用 springockito-annotations 1.0.9 进行集成测试。

我有以下 Controller :

@Autowired
public Controller(
@Qualifier("passwordService ") PasswordService passwordService ,
@Qualifier("validator") Validator validator,
@Qualifier("reportService") ReportService reportService,
DateCalculator dateCalculator,
Accessor accessor){
this.passwordService = passwordService;
this.validator = validator;
this.reportService = reportService;
this.dateCalculator = dateCalculator;
this.accessor = accessor;
}

在测试中,我将使用 @ReplaceWithMock 注释从上下文中替换 bean。

但不幸的是,它仅适用于没有@Qualifier 注释的依赖项。

也就是说,我的测试看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(loader = SpringockitoAnnotatedContextLoader.class, classes = {TestContext.class})
public class ControllerTest {

@Autowired
@ReplaceWithMock
private PasswordService passwordService ;
@Autowired
@ReplaceWithMock
private Validator validator;
@Autowired
@ReplaceWithMock
private ReportService reportService;
@Autowired
@ReplaceWithMock
private DateCalculator dateCalculator;
@Autowired
@ReplaceWithMock
private Accessor accessor;

@Autowired
private Controller controller;

}

在最后一种情况下,在初始化上下文后,只有 DateCalculator 和 Accessor bean 正确替换为所需的模拟,但另一个 bean 从主上下文 Autowiring 为普通 bean

调试后发现QualifierAnnotationAutowireCandidateResolver 无法正确识别bean。在下面从 229 开始的行中:

RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());

Spring 试图从mocked dependency 中提取限定符,但它是空的。

很高兴知道如何使用 @Qualifier 正确替换依赖项以模拟对象。

最佳答案

编辑:添加了指向白盒替代品的链接,它在更高版本的 Mockito 中消失了

可以使用 mockitos @Mock@InjectMocks 将东西注入(inject)到您要测试的类中,如另一篇文章中所建议的。我曾经认为这是测试 spring 托管 beans 的好方法,但现在我认为这是有问题的;如果由 @InjectMocks 完成的注入(inject)失败,它会悄无声息地进行,而且您不知道为什么。创建测试时它是可以管理的,但是当你有一些像这样的测试时,由于一个小的无意的小错误,几个测试开始失败并出现空指针更改某人所做的应用程序上下文,或者在引入轻微异常或类似情况的合并之后,它变得比需要的更困惑。

我建议您改用 mockitos Whitebox,请参阅下面的示例。有了它,你可以明确地告诉你想用什么对象“注入(inject)”哪个字段,在复杂的情况下,你可以注入(inject)多个对象。 Mockito 在注入(inject)时使用 Whitebox(但会吞下所有异常)。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration( /*something that fits your setup*/ )
public class ControllerTest {
@Autowired
private PasswordService passwordService ;
@Autowired
private Validator validator;
@Autowired
private ReportService reportService;



@Autowired
private Controller testObject;

@Before
public void setupBefore() {

//Since this "injection" is done manually the qualifiers does not matter
Whitebox.setInternalState(testObject, "passwordService", passwordService);
Whitebox.setInternalState(testObject, "validator", validator);
Whitebox.setInternalState(testObject, "reportService", reportService);
}

@Test
public void testSomething() {
}
}

如果您正在进行常规单元测试,Whitebox 可以帮助您在没有 spring 上下文的情况下进行测试。我可以强烈推荐这种方法(但它有点偏离主题,我不会发布我在注意到您正在进行集成测试之前写的示例;))。


编辑:如果您使用的是更高版本的 Mockito,您会注意到 Whitebox 已经消失,那么该怎么办呢?我遇到了这种情况,并寻求建议:What do I use instead of Whitebox in Mockito 2.2 to set fields?

关于java - @ReplaceWithMock 与 @Qualifier,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26032594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com