java - 如何使用 JUnit 或 Mockito 测试使用 Random() 的方法(不带参数和返回值)

标签 java unit-testing mockito tdd junit5

我正在学习成为一名 Java 开发人员,现在我正在学习测试驱动开发,这意味着我对 JUnit 和 Mockito 还很陌生。

我已经挣扎了一段时间了,但我陷入了困境。

我不知道如何测试这个没有参数、没有返回值和随机发生器的特定方法。

旧逻辑:

public void getPlayerToStart(int randomNr) {
    if (randomNr == 1) {
        currentPlayer = p1;
        opponentPlayer = p2;
    } else {
        currentPlayer = p2;
        opponentPlayer = p1;
    }
}

旧测试

@Test
void testSetCurrentPlayerSetToPlayer1() {
    gameEngine.getPlayerToStart(1);
    assertEquals(gameEngine.getP1(), gameEngine.getCurrentPlayer());
    assertEquals(gameEngine.getP2(), gameEngine.getOpponentPlayer());
}

@Test
void testSetCurrentPlayerSetToPlayer2() {
    gameEngine.getPlayerToStart(2);
    assertEquals(gameEngine.getP2(), gameEngine.getCurrentPlayer());
    assertEquals(gameEngine.getP1(), gameEngine.getOpponentPlayer());
}

新逻辑:

public void getPlayerToStart() {
    Random rand = new Random();
    int randomNr = rand.nextInt(2) + 1;
    if (randomNr == 1) {
        currentPlayer = p1;
        opponentPlayer = p2;
    } else {
        currentPlayer = p2;
        opponentPlayer = p1;
    }
}

我不确定如何在没有参数“randomNr”的情况下测试 getPlayerToStart() ..有人可以指出我正确的方向吗!

提前致谢。

最佳答案

请始终记住,“天哪,这很难测试”的想法是 TDD 试图向您尖叫,设计需要审查。

I have no idea how to test this particular method that has no arguments, no return value and a randomizer.

随机数是一种副作用,就像 I/O 或时间一样,应该在设计中以这种方式处理。

也就是说,如果您正在进行 TDD,您应该认识到的一件事是,随机性的来源是系统的输入;它是 imperative shell 的一部分它由运行测试时的测试工具提供,并由生产中的组合根提供。

可测试的方法将“生成种子”与“从种子计算状态”分开;单元测试对于后一点来说非常有用,因为纯函数真的很容易测试。生成随机数是 state of sin级别很难测试,但是通过一些设计,您可以将其周围的代码简化到“显然没有缺陷”。

您可能还想查看Writing Testable Code ,作者 Misko Hevery,或 Tales of the Fischer King .

关于java - 如何使用 JUnit 或 Mockito 测试使用 Random() 的方法(不带参数和返回值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53110890/

相关文章:

java - 如何为方法参数中具有私有(private)枚举的方法编写 JUnit 测试用例

java - 将单元格放置在网格(表)中的算法

java - 记录格式错误的 Axis2 请求

java - 在带有自定义标签的android中使用 block 模板引擎

Android 单元测试 - 如何在与应用程序相同的项目中运行测试?

unit-testing - 使用 Mockito 多次调用相同的方法和不同的输出

java - 为自定义驱动程序创建 GraphicsDevice

java - 如何在生产中使用 CDI 测试类时注入(inject)模拟

javascript - 是否有 Jasmine 匹配器来比较对象的属性子集

scala - 如何使用 Mockito 模拟返回值类实例的函数?