Java单元测试学习总结

0 单元测试原则

  • 自动化:为了提高效率,单元测试应该是自动定期执行,这样完全自动化才能保证对系统有效回归验证

  • 独立性:单元测试用例间不能相互调用,也不能依赖执行的先后次数

  • 可重复: 不受外部环境影响,例如远程外部服务、MQ等。这是为了保证持续继承的可用性。

1 单元测试工具

工欲善其事,必先利其器。Java写单元测试常需要泳道下列工具:

  • 测试框架:Junit
  • 断言工具:AssertJ
  • 模拟框架:Mockito

通过这些工具,我们可以对返回值、系统内部状态进行测试。如果有外部依赖,可以通过模拟外部框架,对外部依赖隔离,最终实现单元测试。

常见的模拟框架有

  • Mockito
  • PowerMock
  • JMockit

Mockito使用样例如下:

依赖

        <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.6.28</version>
            <scope>test</scope>
        </dependency>

模拟Iterator及期望的结果

public class Test {

    @Before
    public void setup() {
        MockitoAnnotations.openMocks(this);
    }


    @Test
    public void testIterator() {
        Iterator iterator = Mockito.mock(Iterator.class);
        Mockito.when(iterator.next()).thenReturn("1").thenReturn("2");
        String result = iterator.next() + "/" +iterator.next();
        Assert.assertEquals(result,"1/2");
    }
}

2 Java Web应用分层测试方法

当前Java web应用常见结构分为三层,针对每层进行单侧需要使用不同的方法

  • Controller
  • Service
  • DAO

Controller层:Controller依赖容器,一般测试时需要启动项目,因此单测执行时间长。因此可以考虑使用Spring-test来对Controller测试。借助MockMvc来进行Controller测试

Service层:Service通常会依赖Dao及RPC,因此构造环十分麻烦,也很难保证单侧可重复执行。因此Service的测试思路是通过Mock技术对外部依赖进行隔离。如下Mock RemoteService,并注入到DeepLocalService中,实现隔离,完成单测。


public interface RemoteService {
    String get();
}


public class DeepLocalService implements LocalService{

    private RemoteService remoteService;

    @Override
    public String print() {
        return remoteService.get();
    }
}


public class Test {

    @InjectMocks
    private DeepLocalService localService;

    @Mock
    private RemoteService remoteService;

    @Before
    public void setup() {
        MockitoAnnotations.openMocks(this);
        Mockito.when(remoteService.get()).thenReturn("test");
    }

    @Test
    public void testLocalRemote() {
        String result = localService.print();
        Assert.assertEquals(result,"test");
    }
}

DAO层:DAO层测试依赖数据库中的值,和环境相关,一旦环境变化,单测变无法重复执行。因此处理思路也是通过Mock技术,对数据库进行隔离。DAO的测试通要验证SQL正确性、数据库中结构是否正确等,所以要保证在真是的数据库环境,才能保证代码正确。这时可以考虑使用DBUnit来完辅助成这些工作。

3.让代码更容易测试

有时因为代码的复杂度高、结构不好,最终导致了单元测试的复杂度。不好通常是耦合度高,职责不明确。导致难以对代码的依赖部分模拟替换。 这部分需要重构代码,最终让代码更容易测试。

其次使用的Mock框架可能在功能上有欠缺,例如不支持static关键字等。这是也需要对代码进行简单调整,最终让系统更容易测试。

4.TDD测试驱动开发

为了更好进行测试保证质量,可以基于TDD来进行质量保证。
测试先行,通过测试逐个修复失败的测试用例,最终完成开发。

其过流程下:

开始
测试
编码
设计

5 参考书籍

  • 单元测试的艺术
  • 测试驱动开发的艺术
  • 重构-改善既有代码的设计
  • 敏捷软件开发 - 原则、模式与实践
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你对Java单元测试不了解或不懂如何书写,可以通过以下步骤来学习和掌握: 1. 了解单元测试的概念和重要性:单元测试是用于验证代码中最小可测试单元(例如方法、类)的正确性和可靠性的测试方法。它有助于发现和纠正代码中的错误,并提高代码质量和可维护性。 2. 学习JUnit框架:JUnit是Java最常用的单元测试框架,学习使用JUnit来编写和运行单元测试。了解JUnit的基本注解(如`@Test`、`@Before`、`@After`等)和断言方法(如`assertEquals`、`assertNotNull`等)的用法。 3. 设置测试环境:为了进行单元测试,需要设置一个独立的测试环境,以避免与生产环境的代码和数据产生冲突。可以使用内存数据库、虚拟机等工具来搭建测试环境。 4. 编写测试用例:根据单元测试的需求和代码逻辑,编写相应的测试用例来验证代码的正确性。测试用例应覆盖尽可能多的代码分支和边界条件。 5. 运行和分析测试结果:运行单元测试并查看测试结果,了解测试通过和失败的情况。对于失败的测试用例,分析错误原因,进行必要的调试和修复。 6. 学习其他工具和技术:除了JUnit外,还有其他许多与单元测试相关的工具和技术,如Mockito、PowerMock等。学习如何使用这些工具和技术来进行更复杂的测试。 7. 实践和总结:通过不断实践和总结经验,逐渐提高单元测试的能力和熟练度。参与开源项目或者与其他开发者进行交流,可以获得更多的实践机会和反馈。 最重要的是,持续学习和实践是掌握单元测试的关键,只有通过实践才能掌握其中的技巧和经验,提升能力和水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值