【问题标题】:How to mock class with @ConfigurationProperties in Spring Boot如何在 Spring Boot 中使用 @ConfigurationProperties 模拟类
【发布时间】:2020-09-11 14:39:39
【问题描述】:

我有一个类使用 @ConfigurationProperties 自动连接另一个类。

带有@ConfigurationProperties 的类

@ConfigurationProperties(prefix = "report")
public class SomeProperties {
    private String property1;
    private String property2;
...

Autowires 类 SomeProperties 之上的类

@Service
@Transactional
public class SomeService {
    ....
    @Autowired
    private SomeProperties someProperties;
    .... // There are other things

现在,我想测试 SomeService 类,并且在我的测试类中,当我模拟 SomeProperties 类时,我得到了所有属性的 null 值。

测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SomeProperties.class)
@ActiveProfiles("test")
@EnableConfigurationProperties
public class SomeServiceTest {
    @InjectMocks
    private SomeService someService;

    @Mock // I tried @MockBean as well, it did not work
    private SomeProperties someProperties;

如何模拟 SomeProperties 具有来自application-test.properties 文件的属性。

【问题讨论】:

  • 使用构造函数注入,而不是字段注入。

标签: java spring-boot mocking mockito springmockito


【解决方案1】:

如果您打算绑定属性文件中的值,则不是在模拟 SomeProperties,在这种情况下,将提供 SomeProperties 的实际实例。

模拟:

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {

    @InjectMocks
    private SomeService someService;

    @Mock
    private SomeProperties someProperties;

    @Test
    public void foo() {
        // you need to provide a return behavior whenever someProperties methods/props are invoked in someService
        when(someProperties.getProperty1()).thenReturn(...)
    }

No Mock(someProperties 是一个真实的对象,它绑定了来自某个属性源的值):

@RunWith(SpringRunner.class)
@EnableConfigurationProperties(SomeConfig.class)
@TestPropertySource("classpath:application-test.properties")
public class SomeServiceTest {
   
    private SomeService someService;

    @Autowired
    private SomeProperties someProperties;

    @Before
    public void setup() {
        someService = new someService(someProperties); // Constructor Injection
    }
    ...

【讨论】:

  • 我们是否需要为自动装配的属性注入构造函数
  • @12kadir12 @Autowired 这里的内容不依赖于其他 Bean。所以不行。但是在 @Autowired bean 中存在依赖 bean 的情况下,您可以使用 @MockBean 模拟依赖 bean 并为它们提供存根。
  • 我尝试了这个解决方案,但它不起作用,唯一的区别是我使用的是 .yml 文件而不是属性文件。由于该项目是旧版,因此可能 Spring Boot 版本较旧 :) 你有什么想法吗?
【解决方案2】:

如果您使用 @Mock ,您还需要存根值。默认情况下,所有属性的值为 null。

【讨论】:

    【解决方案3】:

    您需要在 SomeServiceTest.java 的 @Test/@Before 方法中存根所有属性值,例如:

    ReflectionTestUtils.setField(someProperties, "property1", "value1");
    
    ReflectionTestUtils.setField(object, name, value);
    
                             
    

    您还可以通过 Mockito.when() 模拟依赖类的响应

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 2017-05-06
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2015-06-17
      相关资源
      最近更新 更多