Проблема этого подхода в том, что вы полагаетесь на случайное поведение. Существует вероятность того, что в течение 300 бросков требуемое состояние никогда не появится, и модульное тестирование не будет выполнено без ошибочного проверенного кода.
Я хотел бы изучить извлечение логики броска костей из класса Dice через интерфейс (например, "IDiceRoller"). Затем вы можете внедрить ролик случайных игральных костей в ваше приложение и еще один ролик в ваш проект модульного тестирования. Эта воля всегда может вернуть предопределенное значение. Таким образом, вы можете написать тесты для конкретных значений костей, не прибегая к циклу и не надеясь, что значение появится.
Пример:
(код в вашей заявке)
public interface IDiceRoller
{
int GetValue(int lowerBound, int upperBound);
}
public class DefaultRoller : IDiceRoller
{
public int GetValue(int lowerBound, int upperBound)
{
// return random value between lowerBound and upperBound
}
}
public class Dice
{
private static IDiceRoller _diceRoller = new DefaultRoller();
public static void SetDiceRoller(IDiceRoller diceRoller)
{
_diceRoller = diceRoller;
}
public static void Roll(int lowerBound, int upperBound)
{
int newValue = _diceRoller.GetValue(lowerBound, upperBound);
// use newValue
}
}
... и в вашем модульном тестовом проекте:
internal class MockedDiceRoller : IDiceRoller
{
public int Value { get; set; }
public int GetValue(int lowerBound, int upperBound)
{
return this.Value;
}
}
Теперь, в своем модульном тесте вы можете создать MockedDiceRoller
, установить значение, которое вы хотите получить для игры в кости, установить валик для имитации игры в кости в классе Dice
, бросить и проверить это поведение:
MockedDiceRoller diceRoller = new MockedDiceRoller();
diceRoller.Value = 20;
Dice.SetDiceRoller(diceRoller);
Dice.Roll(1, 20);
Assert.IsTrue(Dice.IsCritical);