首页 文章

如何断言为私有字段分配了适当的值?

提问于
浏览
1

我有以下课程:

public class Game {

    @Getter
    private String gameId;

    private String player1Id;

    private String player2Id;

    private String currentPlayer;

    private Board board;

    public Game() {
        board = new Board();
        gameId = UUID.randomUUID().toString();
    }

    public void joinGame(String playerUUID) {
        if (player1 == null) {
            player1 = playerUUID;
            currentPlayer = player1;
        } else if (player2 == null) {
            player2 = playerUUID;
        } else {
            throw new IllegalArgumentException("Cannot join");
        }
    }
    .....
}

我想测试joinGame()方法中的逻辑:

@Test
void testJoinGame() {
    String player1Id = UUID.randomUUID().toString();
    String player2Id = UUID.randomUUID().toString();
    game.joinGame(player1Id);
    game.joinGame(player2Id);
    // this won't compile of course as fields are private
    assertEquals(player1Id, game.player1Id);
    assertEquals(player2Id, game.player2Id);
    assertEquals(player1Id, game.currentPlayer);
}

我在JUnit测试中不应该做两件坏事,因为我经常读到:1 . 更改字段的可见性以使测试工作 . 2.使用反射获取私有字段的值 . (我可以看到这两种方法在我工作的项目中被大量使用,但让我们假装它们不是) .

另外,我有时会读到如果我想测试我的私有字段,则意味着该类的接口定义错误 .

但我想说在这个例子中并非如此:用户id只在类中使用,不需要公开它们 . 我仍然希望确定顺序是正确的:尝试加入游戏的第一个用户将是player1(他/她将是当前用户,例如将进行第一次移动),而第二个玩家2 .

我想问一下测试这种方法的适当解决方案是什么?

2 回答

  • 2

    我同意Tom Hawtin的回答,但我会翻转它们说:

    • 单元测试通常应该避免查看被测试类的内部实现细节 . 他们应该测试类如何与抽象边界之外的事物进行交互 .

    • 如果你在单元测试中看到“内部”,那么如果实现发生变化,测试可能会不必要地破坏 . 是的,然后你可以修复测试,但是你有问题,知道非测试代码是否也被破坏了 .

    另一方面,查看"inside the box"可能会更容易编写测试用例 . 如果您决定采用这种方法:

    • 添加单元测试用例可以使用的getter将允许其他代码依赖于实现细节 . 即使以防止修改的方式实现getter,这也是一个坏主意 . (你仍然有潜在的不必要的耦合,并且你的类实现细节的变化破坏了事情) .

    • 还可以使用反射检查测试用例中的私有字段 . 这是丑陋的,但可以说比getter更好,因为"normal"代码不会这样做 . 实施变更仍有可能破坏单元测试......但仅限于单元测试 .

  • 2

    有两种明显的方法 .

    • 测试实际使用值的位置 . 如果变量没有在课外使用,为什么它们在那里呢?在提供的代码中,您只需要测试是否适当地获得了 IllegalArgumentException .

    • 添加“get”方法 .

    我更喜欢第一个 .

相关问题