NSubstitute Returns 方法和数组

NSubstitute Returns method and arrays

所以我想测试骰子组的掷骰结果,但我不能像这样在 Returns 方法中将数组作为 arg 传递:

    [TestCase(new[]{2, 2, 3, 1, 5}, Category.Yahtzee, 0)]
    public void AddPoints_ForGivenCategory_PointsAreStored(
        int[] rollResults, Category selectedCategory, int expectedScore)
    {
        _randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE).Returns(rollResults); //<-rollResults not allowed
        IDice[] dice = MakeNewDiceSet();

        _game.NewGame("A");
        _game.RollDice(dice);
        _game.AddPoints(selectedCategory);
        var result = _game.GameStatus().First()[selectedCategory];

        Assert.AreEqual(expectedScore, result);
    }

这个问题有什么提示或解决方法吗?还是我被迫这样做:

    [TestCase(2, 2, 3, 1, 5, Category.Yahtzee, 0)]
    public void AddPoints_ForGivenCategory_PointsAreStored(
        int die1, int die2, int die3, int die4, int die5, Category selectedCategory, int expectedScore)
    {
        _randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE).Returns(die1, die2, die3, die4, die5);
        IDice[] dice = MakeNewDiceSet();
        / ...
    }

使用 NSubstitute v3.1.0.0

NSubstitute 没有 Returns<T>(T[] values)(或类似的)。相反,它有 Returns<T>(T initialValue, params T[] otherValues) 来指示我们应该始终为 return 指定至少一个值。当时的目的是避免在空集合的情况下使用 "no values" 存根调用的潜在混淆情况。 (这是空操作吗?还是清除呼叫?)

有几种方法可以获得您想要的行为。一种方法是将值拆分为 "first" 和 "rest":

random.GetRandomNumber(1, 10)
      .Returns(rollResults.First(), rollResults.Skip(1).ToArray());

另一种方法是使用 Queue 和存根 GetRandomNumber() 来使用它:

var rolls = new Queue<int>(rollResults);           
random.GetRandomNumber(1, 10).Returns(_ => rolls.Dequeue());

如果这是您经常需要的东西,可能值得创建您自己的 Returns 扩展,明确定义应如何处理空案例。