NSubstitute возвращает метод и массивы

поэтому я хочу проверить результаты броска набора игральных костей, но я не могу передать массив в качестве аргумента в методе возврата следующим образом:

    [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


person H3ll0    schedule 03.05.2018    source источник
comment
предполагается, что _randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE) возвращает одно число или массив?   -  person Nkosi    schedule 04.05.2018
comment
@Nkosi возвращает int.   -  person H3ll0    schedule 04.05.2018
comment
он видит int[] и пытается вернуть его как результат, который потерпит неудачу, поскольку он ожидает одиночное целое число. вы можете попробовать вернуть функцию в качестве обходного пути, используя счетчик для индекса массива.   -  person Nkosi    schedule 04.05.2018


Ответы (1)


NSubstitute не имеет Returns<T>(T[] values) (или подобного). Вместо этого у него есть Returns<T>(T initialValue, params T[] otherValues), чтобы указать, что мы всегда должны указывать хотя бы одно возвращаемое значение. В то время цель состояла в том, чтобы избежать потенциально запутанного случая заглушки вызова без значений в случае пустой коллекции. (Это не работает? Или это сбрасывает вызов?)

Есть несколько способов получить желаемое поведение. Один из способов — разделить значения на «первые» и «остальные»:

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

Другой подход заключается в использовании очереди и заглушки GetRandomNumber(). потреблять это:

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

Если это то, что вам нужно часто, возможно, стоит создать собственное расширение Returns, которое явно определяет, как следует обрабатывать пустой случай.

person David Tchepak    schedule 04.05.2018
comment
Будет ли Returns<T>(T[] values) реализовано в будущем или нет шансов? - person H3ll0; 04.05.2018
comment
@ H3ll0 Вы можете запросить эту функцию. Я не уверен, что это стоит реализовать из-за потенциальной двусмысленности с пустыми массивами и из-за того, что есть простые альтернативы, но другие соавторы могут чувствовать себя по-другому. Так что наверное стоит обсудить. :) - person David Tchepak; 04.05.2018
comment
Преимущество подхода с очередью заключается в том, что вы получаете исключение, если запрашивается другое значение. - person jeroenh; 23.11.2020