我正在尝试用Mockito模拟对象替换@Autowired
对象。通常的方法是使用Springockito使用xml:
<mockito:mock id="SomeMock" class="com.package.MockInterface" />
目前我正在尝试使用Spring的JavaConfig来完成这项工作。突然之间,Java表达式比xml更加冗长:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MyTestClass {
@Configuration
static class Config {
@Bean
public MockInterface somethingSpecial() {
return Mockito.mock(MockInterface.class);
}
}
@Autowired MockInterface mockObj;
// test code
}
我发现了一个名为Springockito-annotations的库,它允许您执行以下操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=SpringockitoContextLoader.class)
public class MyTestClass {
@Autowired @ReplaceWithMock MockInterface mockObj;
// test code
}
显然,一大堆更漂亮:)唯一的问题是这个上下文加载器不允许我对其他bean使用@Configuration
和JavaConfig(如果我这样做,Spring抱怨没有匹配的候选者那些自动装配的领域。)
你们有没有办法让Spring的JavaConfig和Springockito-annotations发挥得淋漓尽致?或者,是否有另一种创建模拟的简写?
作为一个很好的奖励,使用Springockito和xml配置,我能够模拟出具体的类,而不为它的依赖项提供自动装配候选(如果有的话)。如果没有xml,这是不可能的吗?
答案 0 :(得分:4)
离开现在没有维护的(在撰写本文时)Spingockito-annotations和Mockito,我们有一种非常简单的方法:
@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {
@Mock MockInterface mockObj;
// test code
}
如果您正在使用真实对象,但想在其中模拟依赖项,例如使用DAO测试服务层:
@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {
@InjectMocks RealService;
@Mock MockDAO mockDAO;
// test code
}
最后,这也可以应用于Spring-boot,但在setUp()
中使用注释初始化,直到支持多个类运行器:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyMainSpringBootClass.class)
public class MyTestClass {
@InjectMocks RealService;
@Mock MockDAO mockDAO;
@Before
public final void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
}
// test code
}
答案 1 :(得分:2)
请同时阅读@ethesx的答案, Springockito未经维护
现在可以在没有Springockito-annotations的任何XML文件的情况下模拟Spring应用程序。此解决方案也适用于Spring Boot。
import static org.mockito.BDDMockito.*;
import org.kubek2k.springockito.annotations.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class,
loader = SpringockitoAnnotatedContextLoader.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MainControllerTest {
@Autowired
MainController mainController;
@Autowired
@ReplaceWithMock
FooService fooService;
@Test
public void shouldGetBar() {
//given
given(fooService.result("foo")).willReturn("bar");
//when
Bar bar build = fooService.getBar("foo");
//then
assertThat(bar).isNotNull();
}
}
依赖关系:org.kubek2k:springockito-annotations:1.0.9
答案 2 :(得分:1)
SpringockitoContextLoader
似乎延伸了GenericXmlContextLoader,其描述为:
AbstractGenericContextLoader的具体实现,它从XML资源中读取bean定义。
因此,目前您仅限于xml bean定义。
您可以编写自己的上下文加载器,从SpringockitoContextLoader
类中获取相关部分。看看here开始,也许你可以扩展AnnotationConfigContextLoader例如?