There is the spring-boot application that uses spring-aop. proxy-target-class is true. I'm trying to create a test for a service class. This service depends on a component class. I want to inject a mock into the service instead of the real component.
I found some similar questions:
- Mocking a property of a CGLIB proxied service not working
- Injecting Mockito mocks into a Spring bean
I choose this answer to the last question, and I have tried to implement this approach. I chose it because it is not tied to the implementation details of the proxy classes and I can easily use a config class in other tests.
Below there is the example which simulates the real problem.
@org.aspectj.lang.annotation.Aspect
@org.springframework.stereotype.Component
public class Aspect {
@Before("within(demo.Service)")
public void someAdvice() {
System.out.println("advice");
}
}
@org.springframework.stereotype.Service
public class Service {
@Autowired
private Component component;
public void action() {
System.out.println(component.action());
}
}
@org.springframework.stereotype.Component
public class Component {
public String action() {
return "real action";
}
}
@SpringApplicationConfiguration
public class ServiceTest extends BaseTest {
@Autowired
Service service;
@Test
public void testAction() {
service.action();
}
@Configuration
public static class Config {
@Mock Component mock;
public Config() {
MockitoAnnotations.initMocks(this);
}
@Bean
public Component component() {
Mockito.when(mock.action()).thenReturn("mock action");
return mock;
}
}
}
Complete example: https://github.com/eds0404/spring-inject-mock-into-proxy
The above code is not working as I expect, the service does not use mock ("real action" will be printed if you run test). But the above code works fine if the Component class is not marked with @Component annotation, and its objects are created by the method with @Been annotation.
How to solve this issue? If this is wrong approach, what is best practice?