我正在使用Spring,Junit和Mockito。我需要使用另一种Mockito测试配置(仅根据需要注入模拟豆(在主弹簧配置中定义的bean。嵌套豆在应用程序中已成为@Autowired
。
更新:
根据下面的Alfcope答案,添加name
属性很重要,以便弹簧可以允许主Bean(模拟(覆盖原始的属性。否则您会得到此例外: org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
春季日志中的信息消息显示:
Skipping bean definition for [BeanMethod:name=bar,declaringClass=test.package.MockitoTestConfiguration]: a definition for bean 'bar' already exists. This top-level bean definition is considered as an override.
示例:
我在下面有一个简化的示例,可以使用。在这里,bar是嵌套在foo中,我需要模拟测试栏:
@Component
public class Foo
{
@Autowired
private Bar bar;
public String getResponseFromBar(String request)
{
String response = bar.someMethod(String request);
//do something else with this reponse
return response;
}
}
@Component
public class Bar {
public String someMethod(String request) {
String response = null;
//do something
return response;
}
}
现在要进行测试,假设我想注入一个无知栏而不是真实的栏。如何在下面的测试课上实现这一目标?
@Profile("test")
@Configuration
public class MockitoTestConfiguration {
//adding the name attribute is important.
@Bean(name="mockBar")
@Primary
public Bar bar() {
logger.debug("injecting mock bar");
return Mockito.mock(Bar.class);
}
}
实际测试用例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:test-context.xml")
public class FooTest {
@Autowired
Foo foo;
@Autowired
Bar mockBar; //need this to set up the mock response in the test case.
@Test
public void testAMethodInFoo_WithBarInjectedByMockito() {
//set up the mockBar response
Mockito.when(mockBar.someMethod("1")).thenReturn("1-response");
String response = foo.getResponseFromBar();
assertEquals("1-response", response);
}
}
基于ConfigurationClassBeanDefinitionReader
代码,我猜您正在使用XML配置来定义主Bean。如果是这样,只需在创建Mockito Bean时添加一个名称。
@Bean(name="mockbar")
@Primary
public Bar bar() {
logger.debug("injecting mock bar");
return Mockito.mock(Bar.class);
}
以这种方式,弹簧将使您都拥有两个豆子,并且当您使用@Primary
时,这将是您的测试中使用的豆子。
带有非主要豆的春季覆盖主要豆
ConfigurationClassBeanDefinitionReader代码
另外,如果使用Mockito,则可以执行此操作并完全取消使用额外的MockiteTestConfiguration类,并在测试配置文件中命名为主模拟豆。只需这样做:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:test-context.xml")
public class FooTest {
@Autowired
@InjectMocks
Foo foo;
@Mock
Bar mockBar; //need this to set up the mock response in the test case.
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testAMethodInFoo_WithBarInjectedByMockito() {
//set up the mockBar response
Mockito.when(mockBar.someMethod("1")).thenReturn("1-response");
String response = foo.getResponseFromBar();
assertEquals("1-response", response);
}
}