Spring JUnit: How to Mock autowired component in autowired component

匿名 (未验证) 提交于 2019-12-03 01:56:01

问题:

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?

回答1:

You can provide a new testContext.xml in which the @Autowired bean you define is of the type you need for your test.



回答2:

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");    } 


回答3:

Spring Boot 1.4 introduced testing annotation called @MockBean. So now mocking and spying on Spring beans is natively supported by Spring Boot.



回答4:

You can override bean definitions with mocks with spring-reinject https://github.com/sgri/spring-reinject/



回答5:

I created blog post on the topic. It contains also link to Github repository with working example.

The trick is using test configuration, where you override original spring bean with fake one. You can use @Primary and @Profile annotations for this trick.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!