使用 Mockito 和 Junit 时如何自动装配 spring bean?

How to AutoWire spring beans when using Mockito and Junit?

我正在尝试设置我的 class 以便在 Junit 中使用。

但是当我尝试执行以下操作时出现错误。

当前测试Class:

public class PersonServiceTest {

    @Autowired
    @InjectMocks
    PersonService personService;

    @Before
    public void setUp() throws Exception
    {
        MockitoAnnotations.initMocks(this);
        assertThat(PersonService, notNullValue());

    }

    //tests

错误:

org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'personService'
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

我该如何解决这个问题?

您没有在代码中模拟任何内容。 @InjectMocks 设置一个 class 将注入模拟的位置。

您的代码应如下所示

public class PersonServiceTest {

    @InjectMocks
    PersonService personService;

    @Mock
    MockedClass myMock;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        Mockito.doReturn("Whatever you want returned").when(myMock).mockMethod;


    }

    @Test()
      public void testPerson() {

         assertThat(personService.method, "what you expect");
      }

另一个解决方案是使用带有静态内部配置的 @ContextConfiguration 注解 class 像这样:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PersonServiceTest {
    @Autowired
    PersonService personService;

    @Before
    public void setUp() throws Exception {
        when(personService.mockedMethod()).thenReturn("something to return");
    }

    @Test
    public void testPerson() {
         assertThat(personService.method(), "what you expect");
    }

    @Configuration
    static class ContextConfiguration {
        @Bean
        public PersonService personService() {
            return mock(PersonService.class);
        }
    }
}

无论如何,您需要模拟您要测试的方法在内部使用的东西,以获得该方法所需的行为。模拟您正在测试的服务没有意义。

你误解了这里模拟的目的。

当您像这样模拟一个 class 时,您是在假装它已被注入到您的应用程序中。这意味着你不想注入它!

解决方案:将您打算注入的任何 bean 设置为 @Mock,然后通过 @InjectMocks.

将它们注入到您的测试 class 中

不清楚您要注入的 bean 在哪里,因为您所拥有的只是定义的服务,但是...

@RunWith(MockitoJUnitRunner.class);
public class PersonServiceTest {

    @Mock
    private ExternalService externalSvc;

    @InjectMocks
    PersonService testObj;
}

如果我没记错的话...经验法则是你不能同时使用两者..你要么 运行 使用 MockitojunitRunner 或 SpringJUnitRunner 的单元测试用例你不能同时使用它们。