使用 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 的单元测试用例你不能同时使用它们。
我正在尝试设置我的 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
.
不清楚您要注入的 bean 在哪里,因为您所拥有的只是定义的服务,但是...
@RunWith(MockitoJUnitRunner.class);
public class PersonServiceTest {
@Mock
private ExternalService externalSvc;
@InjectMocks
PersonService testObj;
}
如果我没记错的话...经验法则是你不能同时使用两者..你要么 运行 使用 MockitojunitRunner 或 SpringJUnitRunner 的单元测试用例你不能同时使用它们。