如何在Spring Boot中使用@ConfigurationProperties模拟类

huangapple go评论55阅读模式
英文:

How to mock class with @ConfigurationProperties in Spring Boot

问题

我有一个类使用 @ConfigurationProperties 自动装配另一个类

### 使用 @ConfigurationProperties 的类

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

### 自动装配上述 SomeProperties 类的类

    @Service
    @Transactional
    public class SomeService {
        ....
        @Autowired
        private SomeProperties someProperties;
        .... // 还有其他内容

现在我想测试 **SomeService**在我的测试类中当我模拟 **SomeProperties** 类时所有属性的值都为 `null`。

### 测试类

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

        @Mock // 我尝试过 @MockBean,但没有成功
        private SomeProperties someProperties;

如何在模拟拥有来自 `application-test.properties` 文件的属性的 **SomeProperties**
英文:

I have a class that Autowires another class with @ConfigurationProperties.

Class with @ConfigurationProperties

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

Class that Autowires above class SomeProperties

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

Now, I want to test SomeService class and in my test class when I mock SomeProperties class, I am getting null value for all the properties.

Test class

@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;

How can I mock SomeProperties having properties from application-test.properties file.

答案1

得分: 3

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

ReflectionTestUtils.setField(someProperties, "property1", "value1");

ReflectionTestUtils.setField(object, name, value);

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

英文:

You need to stub all the property values in @Test/@Before methods of SomeServiceTest.java like :

ReflectionTestUtils.setField(someProperties, "property1", "value1");

ReflectionTestUtils.setField(object, name, value);

You can also mock the reponse for dependent classes via Mockito.when()

答案2

得分: 3

以下是您要翻译的内容:

如果您打算从属性文件绑定值,那么您不应该对 SomeProperties 进行模拟。在这种情况下,会提供 SomeProperties 的实际实例。

模拟示例:

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {

    @InjectMocks
    private SomeService someService;

    @Mock
    private SomeProperties someProperties;

    @Test
    public void foo() {
        // 每当在 someService 中调用 someProperties 的方法/属性时,您需要提供返回行为
        when(someProperties.getProperty1()).thenReturn(...);
    }
}

非模拟示例(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); // 构造函数注入
    }
    ...
}
英文:

You are not mocking SomeProperties if you intend to bind values from a properties file, in which case an actual instance of SomeProperties would be provided.

Mock:

@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 is an real object that binds its values from some propertysource):

@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
    }
    ...

答案3

得分: 1

如果您正在使用@Mock ,您还需要对值进行存根处理。默认情况下,所有属性的值都将为null。

英文:

If you are using @Mock , you need to stub the values as well. By default the value will be null for all the properties.

huangapple
  • 本文由 发表于 2020年9月11日 22:39:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63849245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定