51Testing软件测试论坛
标题: JMockit 如何 mock 异常 [打印本页]
作者: 胖虎 时间: 2019-3-22 15:35
标题: JMockit 如何 mock 异常
后来发现用 JMockit 来 mock 异常根本没有之前文中描述的那么复杂,其实还是在那个 result 上,给它赋个异常实例就轻而易举的解决了,只需如此
- new Expectations(MyService.class, ExternalService.class) {
- {
- ExternalService.fetchData();
- result = new NetworkException("No IPAddress ");
- }
- };
复制代码 做过几篇 JMockit 使用 Expectations 来 Mock 方法,私有方法,私有属性的的日志,今天工作上突然有个需求是要 Mock 异常。现在再也不能为了跑个单元测试而去拔下网线了,也不该人为的去制造其他混乱来测试。开始是想能不能用 Expectations 来 Mock 异常,尚未发现相关的属性可以设置,没有类似 result 那样的属性,比如想像中有个 exception/throwable 属性:
- new Expectations(MyService.class, ExternalService.class) {
- {
- ExternalService.fetchData();
- throwable = new NetworkException("No IPAddress ");
- }
- };
复制代码可是没有 throwable 个属性,至少我还不知道如何用 Expectations 来 Mock 异常,此路不通,所以只得另辟溪径。我们可以直接 new MockUp 来创建类,这比创建一个 MockClass 来得轻量级些。
下面是一个完整例子,由四个类构成,今次列出
1. 要抛出的异常类 NetworkException.java
- package
- cc.unmi;
-
- public
- class NetworkException extends
- RuntimeException {
- public
- NetworkException(String message) {
- super(message);
- }
- }
复制代码
2. 被测试类 MyService.java
- package
- cc.unmi;
-
- public
- class MyService {
- public
- static String fetchData(String name) {
- return
- ExternalService.fetchByHttp(name);
- }
- }
复制代码调用 ExternalService.fetchByHttp() 方法,我们的测试用例将要 Mock 住这个方法,并抛出 NetworkException 异常。
3. 外部类,待 Mock 的 ExternalService.java
- package
- cc.unmi;
-
- public
- class ExternalService {
- public
- static String fetchByHttp(String name) {
- String result = null;
- try
- {
- // do something
- } catch
- (Exception ex) {
- throw
- new NetworkException(ex.getMessage());
- }
- return
- result;
- }
- }
复制代码这是个示例方法,就上面的代码正常执行时肯定不会抛出 NetworkException 异常。我们假定在 //do something 的代码可能会抛出 NetworkException 异常,但我们可以在 Mock 方法中立即呈现出这个异常来。
4. 测试类 MyService.java,并完成异常的 Mock
- package
- cc.unmi;
-
- import
- mockit.Mock;
- import
- mockit.MockUp;
-
- import
- org.junit.Rule;
- import
- org.junit.Test;
- import
- org.junit.rules.ExpectedException;
-
- public
- class MyServiceTest {
-
- @Rule
- public
- ExpectedException expectedEx = ExpectedException.none();
-
- @Test
- public
- void testFetchData() {
- new
- MockUp<ExternalService>() {
- @Mock
- public
- String fetchByHttp(String name) {
- throw
- new NetworkException("No IPAddress");
- }
- };
-
- expectedEx.expect(NetworkException.class);
- expectedEx.expectMessage("No IPAddress");
-
- MyService.fetchData("Yanbin");
- }
- }
复制代码这里用 new MockUp<>(){@Mock...} 的方式来 Mock 方法,我们也可以用 @MockClass..@Mock 的方式来创建 Mock 类/方法,但要笨重些。目前我们项目中基本摒弃了用 @MockClass 创建外部 Mock 类的做法,因为一般 Mock 类一般是与某一个测试方法紧密联系着的。
也要注意到 fetchByHttp() 本是个静态方法,但此处不能写成 public String static fetchByHttp(), 但去掉 static 也不会影响到 Mock 的效果。
测试运行成功,能够断言到所期待的异常类型和消息。
下面为演示 Mock 异常的正确而有效性,故意把 expectedEx.epectMessage("No IPAddress") 改成 expectedEx.epectMessage("NoNo IPAddress"),这样 JUnit 更能爆出有助于理解的错误信息来
欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) |
Powered by Discuz! X3.2 |