使用Mockito模拟异常:意外异常错误

时间:2017-03-23 16:15:01

标签: java unit-testing junit mocking mockito

这是我服务的代码:

public class Service {
   public Object serviceMethod() throws MyException {
      @Autowired
      Dao dao;

      try {
         return dao.dao_method();
      } catch (ExceptionFromDaoMethod e) {
         throw (new MyException());
      }
   }
}

我想写一个简单的单元测试;这是我的测试用例:

@Mock
Dao dao;

@InjectMocks
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   when(service.serviceMethod()).thenThrow(new MyException());
}

此测试失败,因为我有一个意外的异常:

  

预期的异常是MyException但是   org.mockito.exception.base.MockitoException

为什么呢?解决方案是什么?

更新 感谢@Maciej Kowalski我注意到我在条件下使用而不是真正的类而不是模拟的类。 所以我在单元测试中向服务添加了注释@Spy
新测试的代码是:

@Mock
Dao dao;

@InjectMocks
@Spy
Service service;

@Before
MockitoAnnotations.initMocks(this);

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doThrow(new MyException()).when(service.serviceMethod());
}

但现在我遇到了这个问题:

  

预期的异常是MyException但是   

2 个答案:

答案 0 :(得分:2)

你必须@spy服务,因为我假设你正在使用它作为调用真实实现的实例。

所以试试这个:

@InjectMocks
@Spy
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doThrow(new MyException()).when(service).serviceMethod();
}

请记住在模拟@Spy时从doXX开始。

<强>更新

如果你想模拟dao调用(这是一个更好的测试候选人..),如果你只想使用普通的Mockito,你将不得不做一些改变。

如果dao不是你的实例依赖项,那么你将不得不改变你的prod方法:

public class Service {
   public Object serviceMethod() throws MyException {
      Dao dao = getDaoInstance();
      try {
         return dao.dao_method();
      } catch (ExceptionFromDaoMethod e) {
         throw (new MyException());
      }
   }

   Dao getDaoInstance(){
      return new Dao();
   }
}

你的测试课应该或多或少地像这样:

@Mock
Dao dao;

@Spy
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doReturn(dao).when(service).getDaoInstance();

   when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod());

   service.serviceMethod();
}

答案 1 :(得分:0)

最后我找到了一个解决方案:为Spring项目创建单元测试比我预期的更具挑战性(至少只使用Mockito Framework),所以我找到了一个使用一些Spring Annotations的解决方案

所以这是我的新工作测试:

@MockBean
Dao dao;

@Autowired
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod());
}