Spring配置-注入模拟bean
我正在使用Spring、Junit和Mockito。我需要使用另一个mockito测试配置(仅在需要时注入模拟bean)覆盖主spring配置中定义的bean。嵌套bean已在应用程序中进行了Spring配置-注入模拟bean,spring,junit,mockito,Spring,Junit,Mockito,我正在使用Spring、Junit和Mockito。我需要使用另一个mockito测试配置(仅在需要时注入模拟bean)覆盖主spring配置中定义的bean。嵌套bean已在应用程序中进行了@Autowired 更新: 根据下面的答案,添加name属性非常重要,这样spring就可以允许主bean(mock)覆盖原始bean。否则会出现以下异常: org.mockito.exceptions.misusing.MissingMethodInvocationException: when()需要
@Autowired
更新:根据下面的答案,添加
name
属性非常重要,这样spring就可以允许主bean(mock)覆盖原始bean。否则会出现以下异常:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when()需要的参数必须是“模拟的方法调用”。
例如:
when(mock.getArticles())。然后返回(articles)代码>
spring日志中的信息消息显示:
跳过[BeanMethod:name=bar,declaringClass=test.package.MockitoTestConfiguration]的bean定义:bean“bar”的定义已经存在。此顶级bean定义被视为覆盖。
示例:
下面我有一个简单的例子。这里,Bar是嵌套在Foo中的,我需要模拟Bar进行测试:
@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;
}
}
现在进行测试,假设我想注入一个mockbar,而不是真正的bar。我怎样才能在下面的测试课上做到这一点
@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。如果是这样,在创建mockitobean时只需添加一个名称
@Bean(name="mockbar")
@Primary
public Bar bar() {
logger.debug("injecting mock bar");
return Mockito.mock(Bar.class);
}
这样,Spring将允许您同时拥有这两个bean,并且当您使用@Primary
时,它将是您的测试所使用的bean
或者,如果您使用Mockito,您可以这样做,并在测试配置文件中完全取消额外的MockitoTestConfiguration类和命名的主mockbean。就这么简单:
@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);
}
}
我补充了更多细节。增加一个名字并不能解决我想要达到的目标。这些bean是自动连接的。我看不出自动连接的bean有任何问题。那很好。使用名称是否会出现相同的“错误”?很抱歉,我的配置文件存在其他一些配置问题,导致我以前的测试无法运行。我用name
属性重新测试了它,结果很好。另外,我不需要@injectmock
。我会为他人的利益而更新。