单元测试框架TestableMock快速入门(五):复用Mock类与方法

目录

一、概述

二、复用Mock类

三、复用Mock方法


一、概述

“Don't Repeat Yourself”是软件开发过程当中的一项重要原则(即“DRY原则”),在编写测试代码时,有些通用的基础功能调用语句常常出现在许多相似的业务类里,若测试中需要Mock这些调用,就要在各个测试类中重复提供同样的Mock方法。而通过Mock方法的复用机制,能够很好的避免编写臃肿重复Mock代码的麻烦。

TestableMock支持两种粒度的Mock复用方式:复用Mock类复用Mock方法

二、复用Mock类

如果有两个或以上测试类需要Mock的方法近乎相同,那么采用类级别的Mock复用就是最省心的一种方式。

进行类级别的Mock复用,只需将Mock容器定义为独立的类,然后在要使用它的测试类上通过@MockWith进行引用。例如:

@MockWith(ServiceMock.class)
public class AaaServiceTest {
    ...
}

@MockWith(ServiceMock.class)
public class BbbServiceTest {
    ...
}

public class ServiceMock {
    ...
}

这样在AaaServiceTestBbbServiceTest类中的测试用例在执行时,都会用ServiceMock容器类中定义的Mock方法进行调用匹配和Mock替换。

下面我们通过一个简单的示例,说明如何复用Mock类。

【a】编写TestService,模拟服务提供者提供接口给其他消费者使用

package com.alibaba.demo.basic;

public class TestService {
    public String test01() {
        return "TestService#test01";
    }

    public String test02() {
        return "TestService#test02";
    }

    public String test() {
        return test01() + " & " + test02();
    }

}

【b】编写两个服务消费者,调用服务提供者TestService的接口

package com.alibaba.demo.basic;

public class AaaService {

    private TestService testService = new TestService();

    public String test01() {
        return testService.test();
    }

}
package com.alibaba.demo.basic;

public class BbbService {
    private TestService testService = new TestService();

    public String test01() {
        return testService.test();
    }

}

【c】编写针对TestService的Mock容器类

使用注解@MockWith(TestServiceMock.class)关联抽取出来的公共Mock类。

package com.alibaba.demo.basic;

import com.alibaba.testable.core.annotation.MockMethod;

/**
 * 针对TestService的Mock容器类
 */
class TestServiceMock {

    @MockMethod(targetClass = TestService.class)
    public String test01() {
        return "ServiceMock#Mock#test01";
    }

    @MockMethod(targetClass = TestService.class)
    public String test02() {
        return "ServiceMock#Mock#test02";
    }

}

【d】编写测试类AaaServiceTest

同样的,使用注解@MockWith(TestServiceMock.class)关联抽取出来的公共Mock类。

package com.alibaba.demo.basic;

import com.alibaba.testable.core.annotation.MockWith;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@MockWith(TestServiceMock.class)
public class AaaServiceTest {

    private AaaService aaaService = new AaaService();

    @Test
    public void test01() {
        String result = aaaService.test01();
        System.out.println("result = " + result);
        Assertions.assertEquals("ServiceMock#Mock#test01 & ServiceMock#Mock#test02", result);
    }

}

【e】编写测试类BbbServiceTest

package com.alibaba.demo.basic;

import com.alibaba.testable.core.annotation.MockWith;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@MockWith(TestServiceMock.class)
public class BbbServiceTest {

    private BbbService bbbService = new BbbService();

    @Test
    public void test01() {
        String result = bbbService.test01();
        System.out.println("result = " + result);
        Assertions.assertEquals("ServiceMock#Mock#test01 & ServiceMock#Mock#test02", result);
    }

}

【f】运行单元测试

 

 可以看到,单元测试是成功通过的,以上就是关于如何通过抽取公共的Mock来实现Mock复用。

三、复用Mock方法

实际场景中,相比一次性复用整个Mock类的情况,更常见的是对部分高频Mock方法进行复用。

Mock方法的复用可以通过Mock容器类的继承来实现,父类中定义的所有Mock方法都会在子类中自然存在,例如:

public class AaaServiceTest {
    public static class Mock extends BasicMock {
        ...
    }
    ...
}

public class BbbServiceTest {
    public static class Mock extends BasicMock {
        ...
    }
    ...
}

public class BasicMock {
    @MockMethod(targetClass = UserDao.class)
    protected String getById(int id) {
        ...
    }
}

则名为getById的Mock方法在AaaServiceTestBbbServiceTest的测试用例执行时都会生效。

同样通过一个示例看下如何通过Mock类的继承实现Mock方法的复用。

【a】编写服务提供者接口

package com.wsh.testable.mock.testablemockdemo;

public class UserDao {

    protected String getById(int id) {
        return String.valueOf(id);
    }

    public String test(int id) {
        return getById(id);
    }

}

【b】编写两个服务消费者,调用服务提供者UserDao的接口

package com.wsh.testable.mock.testablemockdemo;

public class AService {

    private UserDao userDao = new UserDao();

    public String test(int id) {
        return userDao.test(id);
    }

}
package com.wsh.testable.mock.testablemockdemo;

public class BService {

    private UserDao userDao = new UserDao();

    public String test(int id) {
        return userDao.test(id);
    }

}

【c】编写Mock容器基类

package com.wsh.testable.mock.testablemockdemo;

import com.alibaba.testable.core.annotation.MockMethod;

public class UserDaoMock {
    @MockMethod(targetClass = UserDao.class)
    protected String getById(int id) {
        return "Hello," + id;
    }
}

【d】编写测试类AServiceTest

Mock静态内存容器类,通过继承Mock基类实现Mock方法复用。

package com.wsh.testable.mock.testablemockdemo;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class AServiceTest {

    private AService aService = new AService();

    public static class Mock extends UserDaoMock {

    }

    @Test
    public void test() {
        String result = aService.test(123456);
        System.out.println("result = " + result);
        Assertions.assertEquals("Hello,123456", result);
    }

}

【e】编写测试类BServiceTest

Mock静态内存容器类,通过继承Mock基类实现Mock方法复用。

package com.wsh.testable.mock.testablemockdemo;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class BServiceTest {

    private BService bService = new BService();

    public static class Mock extends UserDaoMock {

    }

    @Test
    public void test() {
        String result = bService.test(789);
        System.out.println("result = " + result);
        Assertions.assertEquals("Hello,789", result);
    }
}

【f】运行单元测试

 

可以看到,我们编写的单元测试用例都是可以成功跑通的。以上就是关于通过继承Mock基类实现Mock方法复用的案例,实际工作中,如果有Mock方法大体类似的场景,我们灵活使用其中一种方式即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值