Injecting @Autowired private field during testing

后端 未结 6 1063
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-29 17:08

I have a component setup that is essentially a launcher for an application. It is configured like so:

@Component
public class MyLauncher {
    @Autowired
            


        
6条回答
  •  囚心锁ツ
    2020-11-29 17:40

    I believe in order to have auto-wiring work on your MyLauncher class (for myService), you will need to let Spring initialize it instead of calling the constructor, by auto-wiring myLauncher. Once that is being auto-wired (and myService is also getting auto-wired), Spring (1.4.0 and up) provides a @MockBean annotation you can put in your test. This will replace a matching single beans in context with a mock of that type. You can then further define what mocking you want, in a @Before method.

    public class MyLauncherTest
        @MockBean
        private MyService myService;
    
        @Autowired
        private MyLauncher myLauncher;
    
        @Before
        private void setupMockBean() {
            doNothing().when(myService).someVoidMethod();
            doReturn("Some Value").when(myService).someStringMethod();
        }
    
        @Test
        public void someTest() {
            myLauncher.doSomething();
        }
    }
    

    Your MyLauncher class can then remain unmodified, and your MyService bean will be a mock whose methods return values as you defined:

    @Component
    public class MyLauncher {
        @Autowired
        MyService myService;
    
        public void doSomething() {
            myService.someVoidMethod();
            myService.someMethodThatCallsSomeStringMethod();
        }
    
        //other methods
    }
    

    A couple advantages of this over other methods mentioned is that:

    1. You don't need to manually inject myService.
    2. You don't need use the Mockito runner or rules.

提交回复
热议问题