通过 Mockito 注入字符串



在我的测试BusinessFlow类中,我有一些私有服务字段和一个带有java String类型的私有字段。

在我的测试课上,我有

@RunWith(MockitoJUnitRunner.class)
public class BusinessFlowTest {
    // How can I mock or spy this?
    private String code = "codeValue";
    @Mock
    private Service1Api service1;
    @Mock
    private Service2Api service2;
    @InjectMocks
    private BusinessFlow flow;
    ...
}

@InjectMocks@Mock注释极大地创建了模拟并注入了服务字段。但是,由于 Mockito 不允许为final类创建模拟,我如何为code字段创建模拟?

我看到的一个选项是使用CharSequence接口而不是String字段类型,但它需要更改BusinessFlow类的代码,我不喜欢这个想法。

更新:BusinessFlow是这样定义的

@Service
public class BusinessFlow {
    @Autowired
    @Qualifier(value = "clientCode")
    private String code;
    @Autowired
    private Service1Api service1;
    @Autowired
    private Service2Api service2;
    ...
}

由于某种原因,我们不使用弹簧集成测试功能,也不想在不同类型的注射(例如CTOR注射(中返工BusinessFlow

模拟旨在

模仿外部依赖项,这些依赖项要么太过禁止,无法在测试上下文中启动,要么不需要这样做。 你模拟服务和DAO层接入点之类的东西,以确保你所做的只是一个单元测试。

您要做的是为您运行的每个测试更改此字段的值,而与模拟无关。 请记住 - 这些模拟是外部依赖项。 您可以轻松控制*进入类的字符串。

有关测试中的示例:

@Test
public void testWithFoo() {
    // given
    flow.setValue("foo");
    // when
    // invoke a pertinent method
    // then
    // observe results
}

*:如果你不能,这是一个重构的好机会。

模拟数据对象或具有可重复或无状态行为的简单类(如JDK提供的类(是不明智的。

由于您遇到的确切问题,不鼓励现场注入。


但是,如果您选择忽略这种公认的智慧,Spring 确实为此目的提供了一个实用程序类:org.springframework.test.util.ReflectionTestUtils

有了这个,你可以注入到你的类中:

 BusinessFlow flow = new BusinessFlow();
 ReflectionTestUtils.setField(flow, "code", "testcode");
 ReflectionTestUtils.setField(flow, "service1", mockService);

当然,你可以直接使用Java Reflection API实现同样的事情,但这稍微方便一些。

被认为是一种非常糟糕的做法,可以模拟java.lang包下的任何内容。此外,不建议在 Spring 中使用现场注入。控制Spring code最便宜的方法是重构类以使用构造函数注入。

@Service
public class BusinessFlow {
    private String code;
    private Service1Api service1;
    private Service2Api service2;
    @Autowired
    public BusinessFlow(@Qualifier(value = "clientCode") String code,
                        Service1Api service1,
                        Service2Api service2) {
        this.code = code;
        this.service1 = service1;
        this.service2 = service2;
    }
}

这不会花费你任何费用,你不必改变BusinessFlow类的客户端(只要它由 Spring 管理(。现在,您可以在不使用 Spring 测试功能的情况下控制注入到类中的数据。

Service1Api service1 = mock(Service1Api.class);
Service2Api service2 = mock(Service2Api.class);
BusinessFlow businessFlow = new BusinessFlow("codeValue", service1, service2);

使用 Apache Commons 反射方法来初始化测试类中的字符串值,如下所示

FieldUtils.writeField(classObject, "variableName", "value", true(;

相关内容

  • 没有找到相关文章

最新更新