【问题标题】:How to mock @Value field using mockito如何使用 mockito 模拟 @Value 字段
【发布时间】:2021-06-30 19:43:09
【问题描述】:

我正在尝试测试一个方法,但是当我的测试方法调用实际方法时,由于存在@Value 字段,实际方法总是接收@Value 字段下定义的值,即 null。您可以看看下面的实际方法和测试方法的代码:

实际方法

public class IndexService {

    @Value("${elasticsearch.index}")
    private String index;

    public boolean index(String id, String json, String index) {
        try {
            createIndex();
            return true;
        } catch (IOException e) {
            log.warn("Exception in indexing data {}", e.getMessage());
        }
        return false;
    }
   private void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
    }
}

下面是我的测试方法:

@Test
    public void IndexServiceIndex() throws IOException {
        CreateIndexRequest request1 = new CreateIndexRequest(index);
        request1.source("{\"name\":true}",XContentType.JSON);
        Mockito.when(indicesClient.create(request1,RequestOptions.DEFAULT))
       .thenReturn(createIndexResponse);
        Boolean indexser = indexService.index("65","{\"name\":molly}","1");
}

下面是CreateIndexRequest class方法:

public CreateIndexRequest(String index) {
        if (index == null) {
            throw new IllegalArgumentException("The index name cannot be null.");
        } else {
            this.index = index;
        }
    }

发生的情况是,当我的测试方法调用实际方法indexService.index("65","{\"name\":molly}","1");,然后控制转到actual method,私有方法createIndex 正在注入index 值,上面定义为 @Value("${elasticsearch.index}") private String index; .因此在 CreateIndexRequest method 中,它总是评估为 null 并抛出异常 IllegalArgumentException("The index name cannot be null.")

我尝试使用ReflectionTestUtils.setField,但我的项目中没有org.springframework.test.util.ReflectionTestUtils 所需的依赖项。还有其他方法可以模拟@Value 字段吗?

【问题讨论】:

  • 查看具有properties 参数的@SpringBootTest
  • 你能给我一些链接来阅读如何使用它吗?还有没有其他方法可以仅使用 mockito 来解决问题?
  • 答案是不要。更改您的类以使用构造函数注入,然后只需调用 new 并将值作为普通参数传递给它。
  • 谢谢@chrylis-cautiouslyoptimistic-,我会试试的。

标签: java spring-boot unit-testing junit mockito


【解决方案1】:

你根本不知道。通常不鼓励使用字段注入,因为它使测试代码变得比实际代码更复杂。要测试您尝试测试的任何内容,请使用任一

  1. 构造函数注入 - 您可以在构造函数参数上 @Value,并且可以通过构造函数放置测试值
  2. setter 注入 - 使用 @Value 注释 setter 方法。它在容器中的工作方式完全相同,如何在测试中使用它是显而易见的
  3. 使用@TestProperties - 但这会修复整个测试类的值
  4. 使用反射 - 这甚至允许您改变最终字段,但是如果涉及 AOP 和代理,这可能无法简单地工作

可能还有许多其他人。我认为1和2是最可行的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 2016-05-08
    相关资源
    最近更新 更多