用模拟测试Spring中的服务,我做错了什么?

时间:2017-03-02 09:35:42

标签: java spring unit-testing mocking

我有一个Spring-boot项目,我有控制器,服务和映射器层。现在我想测试一个服务,我想模拟映射器。我是这样做的:

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
@Transactional
public class SomeServiceTest extends   AbstractTransactionalJUnit4SpringContextTests {

@Mock
private AMapper aMapper;

@Autowired
@InjectMocks
AService aService;


@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    executeSqlScript("classpath:insertSomeData.sql", false);
}

@Test
public void testMethod() throws Exception {
    //prepareSomeData
    aService.callMethod(someData);

    verify(aMapper).callTheRightMethod(rightObject);

}

服务:

@Service
@Transactional(readOnly = true)
public class AServiceImpl implements AService {

@Autowired
BMapper bMapper;

@Autowired
CMapper cMapper;

@Override
@Transactional(readOnly = false)
public SomeReturnObject callMethod(SomeData someData)throws Exception {
     //some execution to obtain aResult

     if(true){
       aMapper.callTheRightMethod(aResult);}
     else 
       aMapper.callWrongMethod(aResult);
}

现在,当我执行测试时,结果为:

Wanted but not invoked:
aMapper.callTheRightMethod{..}
Actually, there were zero interactions with this mock.

当我调试然后我看到该方法被调用,但可能是错误的映射器(不是模拟的)。你有一些提示来解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

我在这里看不到模拟互动录音。它应该在实际调用之前。它应该是这样的。

Mockito.when(aMapper.callTheRightMethod(Mockito.any()).thenReturn(rightObject);

流程应该是这样的。首先记录模拟,然后执行实际调用,最后验证模拟交互。如上所述,测试类不需要@Autowire。请删除它。而是通过将一些数据传递给它的构造函数来创建服务类的新实例。希望这可以帮助。快乐的编码!

答案 1 :(得分:0)

我并不完全明白为什么要启动spring上下文来测试服务层。 一次只测试一个图层。

我将如何解决这个问题。 (如果某些事情无法编译,我的道歉......从我的头脑中写出来)

let typeList = [];
        for (let item of items) {
            if (typeList.indexOf(item.status) < 0) {
                typeList.push(item.status);
            }
        }

const renderList = (status) => {
   //how to get the index here?
}

return(
   { typeList.map(renderList) }
)