我们有一个服务组件(@service),它在内部使用MyBatis来进行CRUD操作。所有组件都由Spring管理。
让我们假设我们的MyBatis映射器文件
class MyBatisMapper{
public void getData(Map<String,Object> arg);
}
在我们的mybatis xml文件中,我们为可调用语句定义了元素。 arg是一个包含IN和OUT参数的地图。
我们的服务组件就像
@Service("myService")
class MyService{
@Autowired
private MyBatisMapper myMapper;
public void processData(){
Map<String,Object> input = new HashMap<String,Object>();
............
............
myMapper.getDat(input);
Object response = input.get("RESPONSE");
//process response and so on
}
我的目标是为服务组件编写Junits,而不必与DB进行交互。所以,我尝试使用JMockIt来模拟一些DAO操作
我的尝试是ike
@Mocked
@Injectable
private MyBatisMapper myMapper;
@Test
public void testService() {
new NonStrictExpectations(){
{
Map<String,Object> input = new HashMap<String,Object>();
input.put("xxx,"yyy");
myMapper.getData(input);
}
};
}
但是当我运行我的测试时,我注意到这个调用是通过实际数据库进行的,而不是通过模拟调用。
如何确保只调用模拟的组件,而不是实际的对象
答案 0 :(得分:0)
@Injectable
模拟实例仅被注入@Tested
个对象。要从模拟方法指定返回值,您需要将其分配给result
字段。因此,测试应如下所示:
@Tested MyService myService;
@Injectable MyBatisMapper myMapper;
@Test
public void testService() {
final Map<String,Object> data = new HashMap<String, Object>();
data.put("RESPONSE", "yyy");
new Expectations() {{
myMapper.getData((Map<String, Object>) any); result = data;
}};
myService.processData();
// Assert some expected outcome.
}
答案 1 :(得分:0)
谢谢Rogerio。我试图按照你提到的方法,但我仍然看到调用转到实际对象。有一点我之前没有提到过。我的项目是基于弹簧的,组件都是自动装配的。
我的测试有
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/test-applicationContext.xml"})
和test-applicationContext.xml进行组件扫描。所以我认为,Spring正在注入忽略模拟指令的实际对象。
我错了吗?