javaspring-bootmockingmockitospringmockito

How to mock class with @ConfigurationProperties in Spring Boot


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.


Solution

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