Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JUnit: How to Mock autowired component in autowired component

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?

like image 838
NeplatnyUdaj Avatar asked Oct 10 '13 15:10

NeplatnyUdaj


People also ask

Can we mock Autowired object?

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!).

Can we use Autowired with @component?

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

What is the difference between @autowired and @mock?

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

Can a spring component be Autowired?

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.


1 Answers

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");    } 
like image 146
Anna Zubenko Avatar answered Oct 13 '22 23:10

Anna Zubenko