I've got a Spring component I'd like to test and this component has an autowired attribute which I need to change for the purpose of unit testing. The problem is, that the class uses the autowired component inside the post-construct method so I'm not able to replace it(i.e. via ReflectionTestUtils) before it's actually used.
How should I do that?
This is the class I want to test:
@Component public final class TestedClass{ @Autowired private Resource resource; @PostConstruct private void init(){ //I need this to return different result resource.getSomething(); } }
And this is the base of a test case:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations= "classpath:applicationContext.xml") public class TestedClassTest{ @Autowired private TestedClass instance; @Before private void setUp(){ //this doesn't work because it's executed after the bean is instantiated ReflectionTestUtils.setField(instance, "resource", new Resource("something")); } }
Is there some way to replace the resource with something else before the postconstruct method is invoked? Like to tell Spring JUnit runner to autowire different instance?
It is because the autowired component requires an special treatment to be “mocked”. This will initialize the application context, but, if your goal is not a integration test, maybe this is unnecessary, because now, you'll have a test case with all dependencies of your project loaded (slow test!).
So the answer is: No, @Autowired does not necessarily mean you must also use @Component . It may be registered with applicationContext. xml or @Configuration+@Bean . @Autowired on the construct makes no sense in the above example...
@InjectMocks is a Mockito mechanism for injecting declared fields in the test class into matching fields in the class under test. It doesn't require the class under test to be a Spring component. @Autowired is Spring's annotation for autowiring a bean into a production, non-test class.
The Spring framework enables automatic dependency injection. In other words, by declaring all the bean dependencies in a Spring configuration file, Spring container can autowire relationships between collaborating beans. This is called Spring bean autowiring.
You could use Mockito. I am not sure with PostConstruct
specifically, but this generally works:
// Create a mock of Resource to change its behaviour for testing @Mock private Resource resource; // Testing instance, mocked `resource` should be injected here @InjectMocks @Resource private TestedClass testedClass; @Before public void setUp() throws Exception { // Initialize mocks created above MockitoAnnotations.initMocks(this); // Change behaviour of `resource` when(resource.getSomething()).thenReturn("Foo"); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With