Spring JUnit: How to Mock autowired component in autowired component

前端 未结 6 1503
花落未央
花落未央 2020-12-02 12:20

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

相关标签:
6条回答
  • 2020-12-02 12:25

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

    0 讨论(0)
  • 2020-12-02 12:31

    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");   
    }
    
    0 讨论(0)
  • 2020-12-02 12:32

    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.

    0 讨论(0)
  • 2020-12-02 12:32

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

    0 讨论(0)
  • 2020-12-02 12:37

    Another approach in integration testing is to define a new Configuration class and provide it as your @ContextConfiguration. Into the configuration you will be able to mock your beans and also you must define all types of beans which you are using in test/s flow. To provide an example :

    @RunWith(SpringRunner.class)
    @ContextConfiguration(loader = AnnotationConfigContextLoader.class)
    public class MockTest{
     @Configuration
     static class ContextConfiguration{
     // ... you beans here used in test flow
     @Bean
        public MockMvc mockMvc() {
            return MockMvcBuilders.standaloneSetup(/*you can declare your controller beans defines on top*/)
                    .addFilters(/*optionally filters*/).build();
        }
     //Defined a mocked bean
     @Bean
        public MyService myMockedService() {
            return Mockito.mock(MyService.class);
        }
     }
    
     @Autowired
     private MockMvc mockMvc;
    
     @Autowired
     MyService myMockedService;
    
     @Before
     public void setup(){
      //mock your methods from MyService bean 
      when(myMockedService.myMethod(/*params*/)).thenReturn(/*my answer*/);
     }
    
     @Test
     public void test(){
      //test your controller which trigger the method from MyService
      MvcResult result = mockMvc.perform(get(CONTROLLER_URL)).andReturn();
      // do your asserts to verify
     }
    }
    
    0 讨论(0)
  • 2020-12-02 12:38

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

    0 讨论(0)
提交回复
热议问题