Springboot & Mockito - 使用 ReflectionTestUtils.setField 调用方法两次



我想在Junit5单元测试中用@Value注释的私有字段注入值。

@Value("$(invoice.maxRetry)")
private maxRetry;

我引用了这个并使用了reflectiontesttils。setField通过注入值解决了我的问题,但在验证no时失败。方法被调用的次数

MyClass:

public class MessageProcessor {

@Value("$(invoice.maxRetry)")
private maxRetry;

protected void handleMessage() {
if(retry > maxRetry) {
kafkaTemplate.sendMessage(msg);
}
}

TestClass:

@ExtendWith(MockitoExtension.class)
public class MessageProcessorTest {
@Mock
private kafkaTemplate kafkaTemplate;
@Mock
private MessageProcessor messageProcessor
@Test
test() {
ReflectionTestUtils.setField(messageProcessor, "maxRetry", "5");
doNothing().when(kafkaTemplate).sendMessage(any());
messageProcessor.handleMessage();
verify(kafkaTemplate).sendMessage(any());
}
}

运行以上测试错误

org.mockito.exceptions.verification.TooManyActualInvocations: 
kafkaTemplate.sendMessage(<any>);
Wanted 1 time:
But was 2

我希望kafkaTemplate.sendMessage();只被调用一次,但在添加ReflectionTestUtils后被调用两次。

需要建议如何解决这个问题。

你可以避免使用ReflectionTestUtils略重构你的类和支持构造注入:

public class MessageProcessor {

private String maxRetry;
private KafkaTemplate template;
// ... any further fields
public class MessageProcessor(@Value("$(invoice.maxRetry)") String maxRetry, KafkaTemplate kafkaTemplate) {
this.maxRetry = maxRetry;
this.kafkaTemplate = kafkaTemplate;
}
}

在测试中,您可以通过手动创建被测试类(MessageProcessor)的实例来控制maxRetry的值。

@ExtendWith(MockitoExtension.class)
public MessageProcessorTest {
@Mock 
private KafkaTemplate kafkaTemplate;
private MessageProcessor messageProcessor;
@BeforeEach
void setUp() {
this.messageProcessor = new MessageProcessor("42", kafkaTemplate);
}
}

…然后只依赖JUnit和Mocktio,它们应该可以帮助你添加验证。

最新更新