使用FizzBu​​zz和Mockito进行单元测试

我有时使用FizzBu​​zz向新手演示单元测试的基础。 尽管FizzBu​​zz确实是一个简单的问题,但是它也可以用于演示更高级的单元测试技术,例如模拟

FizzBu​​zz Kata:

编写一个程序,打印从1到100的数字。但是,对于三个数字的倍数,请打印“ Fizz”,而不是数字;对于五个数字的倍数,请打印“ Buzz”。 对于三和五的倍数的数字,请打印“ FizzBu​​zz ”。

FizzBu​​zz算法的可能解决方案:

public class FizzBuzz {

    private static final int FIVE = 5;
    private static final int THREE = 3;

    public String calculate(int number) {

        if (isDivisibleBy(number, THREE) && isDivisibleBy(number, FIVE)) {
            return "FizzBuzz";
        }

        if (isDivisibleBy(number, THREE)) {
            return "Fizz";
        }

        if (isDivisibleBy(number, FIVE)) {
            return "Buzz";
        }

        return "" + number;
    }

    private boolean isDivisibleBy(int dividend, int divisor) {
        return dividend % divisor == 0;
    }
}

由于上面的代码解决了FizzBu​​zz算法,因此无法解决FizzBu​​zz问题。 要完成它,我们需要使用该算法的代码来打印从1到100的数字。 代码的这一部分可以用来展示在JUnit中使用Mockito进行模拟的想法。

作为此练习的结果,我最终得到了一个NumberPrinter ,它带有两个参数: PrinterNumberCalculator并且具有一个公共方法来打印数字:

public class NumberPrinter {

    private NumberCalculator numberCalculator;
    private Printer printer;

    public NumberPrinter(NumberCalculator numberCalculator, Printer printer) {
        this.numberCalculator = numberCalculator;
        this.printer = printer;
    }

    public void printNumbers(int limit) {
        if (limit < 1) {
            throw new RuntimeException("limit must be >= 1");
        }
        for (int i = 1; i <= limit; i++) {
            try {
                printer.print(numberCalculator.calculate(i));
            } catch (Exception e) {
                // noop
            }
        }
    }
}

public interface NumberCalculator {
    String calculate(int number);
}

public interface Printer {
    void print(String s);
}

引入接口后,我不仅拥有可测试的代码,而且拥有更强大的代码。 为了测试NumberPrinter我只是使用Mockito的强大功能和简单性来模拟依赖项。 使用Mockito批注,配置测试代码的读取效果更好。

Mockito功能展示:

  • 创建和注入模拟
  • 存根方法还可以为连续的方法调用设置不同的行为。
  • 将void方法存入一个异常
  • 验证

使用的注释:

  • @RunWith(MockitoJUnitRunner.class) –在每个测试方法之前初始化@Mock
  • @Mock –将字段标记为模拟
  • @InjectMocks –标记应在其上执行注射的字段
@RunWith(MockitoJUnitRunner.class)
public class NumberPrinterTest {

    @Mock
    private Printer printer;

    @Mock
    private NumberCalculator numberCalculator;

    @InjectMocks
    private NumberPrinter numberPrinter;

    @Test
    public void printsCalculatorResultsHundredTimes() {
        // arrange
        int limit = 100;
        when(numberCalculator.calculate(anyInt()))
                .thenReturn("0")  // first invocation returns "0"
                .thenReturn("1"); // other invocations return "1"
        // act
        numberPrinter.printNumbers(limit);
        // assert
        verify(numberCalculator, times(limit)).calculate(anyInt());
        verify(printer, times(1)).print("0");
        verify(printer, times(limit - 1)).print("1");
        verifyNoMoreInteractions(numberCalculator, printer);
    }

    @Test
    public void continuesOnCalculatorOrPrinterError() {
        // arrange
        when(numberCalculator.calculate(anyInt()))
                .thenReturn("1")
                .thenThrow(new RuntimeException())
                .thenReturn("3");
        // stub the void method with an exception
        doThrow(new RuntimeException()).when(printer).print("3");
        // act
        numberPrinter.printNumbers(3);
        // assert
        verify(numberCalculator, times(3)).calculate(anyInt());
        verify(printer).print("1");
        verify(printer).print("3");

        verifyNoMoreInteractions(numberCalculator, printer);
    }
}

享受Mockito

翻译自: https://www.javacodegeeks.com/2014/11/unit-testing-exercise-with-fizzbuzz-and-mockito.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值