美文网首页
junit4使用

junit4使用

作者: 曼城蓝月亮 | 来源:发表于2017-11-22 17:16 被阅读0次

一、环境

使用idea2017.2.3,maven3.5,基于版本junit4.12,大部分内容基于网上整理而来
pom.xml:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

二、基本测试

要测试的类Calculator,这是一个能够简单实现加减乘除、平方、开方的计算器类

public class Calculator {
    private static int result; // 静态变量,用于存储运行结果

    public void add(int n) {
        result = result + n;
    }

    public void substract(int n) {
        result = result - 1;  //Bug: 正确的应该是 result =result-n
    }

    public void multiply(int n) {
    }         // 此方法尚未写好

    public void divide(int n) {
        result = result / n;
    }

    public void square(int n) {
        result = n * n;
    }

    public void squareRoot(int n) {
        for (; ; ) ;            //Bug : 死循环
    }

    public void clear() {     // 将结果清零
        result = 0;
    }

    public int getResult() {
        return result;
    }
}
快速生成测试类和方法

在类名上,按下alt+enter ,选择Create Test


image.png

选择junit4,选择要测试的方法,这里选择加减乘除


image.png

对生成的测试类CalculatorTest,做一些修改如下

public class CalculatorTest {   
    private static Calculator calculator = new Calculator();

    @Before
    public void setUp() throws Exception {
        calculator.clear();
    }

    @Test
    public void testAdd() {
        calculator.add(3);
        calculator.add(4);
        assertEquals(7, calculator.getResult());

    }

    @Test
    public void testSubstract() {
        calculator.add(8);
        calculator.substract(3);
        assertEquals(5, calculator.getResult());

    }

    @Ignore("Multiply() Not yet implemented")
    @Test
    public void testMultiply() {
        fail("Not yet implemented");
    }

    @Test
    public void testDivide() {
        calculator.add(8);
        calculator.divide(2);
        assertEquals(4, calculator.getResult());

    }

}
注解的说明

@BeforeClass 全局只会执行一次,而且是第一个运行
@Before 在测试方法运行之前运行
@Test 测试方法
@After 在测试方法运行之后允许
@AfterClass 全局只会执行一次,而且是最后一个运行
@Ignore 忽略此方法

方法的说明

这里用到了两个断言
Assert.assertEquals(expected, actual) 传入预期值跟实际值,断言它们相等
Assert.fail(String message) 在不检查任何条件的情况下使断言失败。显示消息

Run整个Test类,显示结果如下:


image.png

三、限时测试

对于循环、数据库查询、网络请求等可能的耗时操作往往需要限定其操作响应时间。
给@Test加上一个参数timeout来设定要限定的时间,单位为毫秒。

 @Test(timeout = 1000)
    public void squareRoot() {
        calculator.squareRoot(4);
        assertEquals(2, calculator.getResult());
    }

Run这个测试方法,因为calculator.squareRoot里面是死循环,所以得到一个超时结果


image.png

四、异常测试

某些情况下,应该抛出异常的,我们也需要测试到这种情况
给@Test加上一个参数expected 来设定预期发生的异常

@Test(expected = ArithmeticException.class)
public void divideByZero(){
      calculator.divide(0);
}

RunTest通过

当然,还可以进行try...catch操作,在catch里面使用断言来处理得到的异常

@Test
public void divideByZero1() {
    try {
        calculator.divide(0);
        Assert.fail("fail");
    } catch (Exception e) {
        Assert.assertTrue(e instanceof ArithmeticException);
    }
}

五、参数化测试

一个方法可能有多个处理分支,要测试到多个不同的分支就需要不同的测试用例,如果按上面的方法来处理,有多少个测试用例就需要写多少个测试方法,junit提供了另外的选择。
测试calculator.Square方法,把它分三类:正数、0、负数,代码如下

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

//(1)步骤一:测试类指定特殊的运行器org.junit.runners.Parameterized
@RunWith(Parameterized.class)
public class SquareTest {
    private static Calculator calculator = new Calculator();
    // (2)步骤二:为测试类声明变量,分别用于存放期望值和测试所用数据。
    private int param;
    private int result;

    // (3)步骤三:为测试类声明一个带有参数的公共构造函数,并在其中为第二个环节中声明的几个变量赋值。
    public SquareTest(int param, int result) {
        this.param = param;
        this.result = result;
    }

    // (4)步骤四:为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对
    @Parameterized.Parameters
    public static Collection data() {
        return Arrays.asList(new Object[][]{
                {2, 4},
                {0, 0},
                {-3, 9},
        });
    }

    // (5)步骤五:编写测试方法,使用定义的变量作为参数进行测试
    @Test
    public void square() {
        calculator.square(param);
        Assert.assertEquals(result, calculator.getResult());
    }
}

Run结果


image.png

六、spring测试

更多的时候,都是在使用spring框架进行开发,所以测试环境也需要基于spring
引入spring

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.11.RELEASE</version>
    <scope>test</scope>
</dependency>

测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SpringTest {

    @Autowired
    private Calculator calculator;

    @Test
    public void testAdd() {
        calculator.clear();
        calculator.add(5);
        Assert.assertEquals(5, calculator.getResult());
    }
}

如果需要在spring框架下使用参数化测试,需要借助TestContextManager类来处理,SpringJUnit4ClassRunner内部其实也是使用TestContextManager来进行的处理

@RunWith(Parameterized.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SpringSquareTest {

    @Autowired
    private Calculator calculator;

    private int param;
    private int result;

    private TestContextManager testContextManager;

    @Before
    public void setUp() {
        //自动注解与@RunWith(SpringJUnit4ClassRunner.class) 效果一样
        testContextManager = new TestContextManager(getClass());
        try {
            testContextManager.prepareTestInstance(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Parameterized.Parameters
    public static Collection data() {
        return Arrays.asList(new Object[][]{
                {2, 4},
                {0, 0},
                {-3, 9},
        });
    }
    
    public SpringSquareTest(int param, int result) {
        this.param = param;
        this.result = result;
    }

    @Test
    public void square() {
        calculator.square(param);
        assertEquals(result, calculator.getResult());
    }
}

七、自定义断言

通过Assert.assertThat(T actual, Matcher<? super T> matcher)来自定义断言

@Test
public void testAssertThat() {
    Assert.assertThat("12321", new BaseMatcher<String>() {
        @Override
        public boolean matches(Object o) {
            return "12321".equals(o);
        }
        @Override
        public void describeTo(Description description) {
            description.appendText("不相等");
        }
    });
}

junit已经内置了一些Matcher,可以直接使用,如

Assert.assertThat("Hello,World", startsWith("Hello"));
Assert.assertThat( "Hello,World", both(startsWith("Hello")).and(endsWith("World")));

参考:

Java单元测试之JUnit篇

Junit4中的新断言assertThat的使用方法

Junit4 Parameterized参数化和自动注解一起使用

相关文章

  • Idea 使用 Junit4 进行单元测试

    [TOC] Idea 使用 Junit4 进行单元测试 1. Junit4 依赖安装 Idea 默认使用 arqu...

  • JUnit4 中@AfterClass @BeforeClass

    JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation: @...

  • junit4使用

    一、环境 使用idea2017.2.3,maven3.5,基于版本junit4.12,大部分内容基于网上整理而来p...

  • Build Instrumented Test

    Setups Instrumented Test是基于JUnit的,使用JUnit4的Test Class风格我们...

  • 同时使用Junit4的@Parameterized参数化测试和S

    同时使用Junit4的@Parameterized参数化测试和Spring容器整合 之剑 2016.4.30 整合...

  • Junit单元测试 | 注解和执行顺序

    JUnit4注解基本介绍JUnit4 中@AfterClass @BeforeClass @after @befo...

  • @Test无效?

    描述: 为什么我的Java里,@Test无法使用 解决: 项目右键,build path,lib添加JUnit4

  • JUnit4 初级使用

    1、什么是Junit4 JUnit是一个开放源代码测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系x...

  • Junit4使用实例

    一、开胃示例 被测试类——获取学生数据: 测试用例: 二、固件测试 就是每个测试方法执行前和后都执行的方法,用于自...

  • JUnit4基本使用

    这里直接使用maven,添加junit的坐标。 最简单的使用 写一个方法类,定义两个方法实现两个数的相加和相减运算...

网友评论

      本文标题:junit4使用

      本文链接:https://www.haomeiwen.com/subject/pkwnvxtx.html