Is looping in unit test bad?

I have a unit test that relies on a random bone roll. I am translating a 20-sided matrix, and if the value is 20, this is considered a critical hit.

What I'm doing right now is rolling a 20-sided die up to 300 times. If any of these clips is 20, I know that I had a critical hit.

Here is what the code looks like:

public class DiceRoll
{
    public int Value { get; set; }
    public bool IsCritical { get; set; }

    // code here that sets IsCritical to true if "Value" gets set to 20
}

[Test]
public void DiceCanRollCriticalStrikes()
{
    bool IsSuccessful = false;
    DiceRoll diceRoll = new DiceRoll();

    for(int i=0; i<300; i++)
    {
        diceRoll.Value = Dice.Roll(1, 20); // roll 20 sided die once
        if(diceRoll.Value == 20 && diceRoll.IsCritical)
        {
            IsSuccessful = true;
            break;
        }
    }

    if(IsSuccessful)
        // test passed
    else
        // test failed 
}

Although the test does exactly what I want, I cannot help but feel that I am doing something wrong.

In the corresponding note, the DiceRoll class also contains other information, but my question in particular is related to the cycle in unit test, so I left it to make it more clear.

+3
source share
3

, . , 300 , unit test , .

Dice (, "IDiceRoller" ). unit test. . , , , .

:

( )

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
    }
}

... unit test:

internal class MockedDiceRoller : IDiceRoller
{
    public int Value { get; set; }

    public int GetValue(int lowerBound, int upperBound)
    {
        return this.Value;
    }
}

, unit test MockedDiceRoller, , , Dice, , :

MockedDiceRoller diceRoller = new MockedDiceRoller();
diceRoller.Value = 20;
Dice.SetDiceRoller(diceRoller);

Dice.Roll(1, 20);
Assert.IsTrue(Dice.IsCritical);
+6

, , , - .

. , 20, , . , , unit test.

unit test, , IFF (if-and-only-if), 20.

, , , , unit test.

+2

:

20 300 1 5 . - unit test - , , , - .

, , , - , , ? , , , - . , , 400 ( : 1 814 ).

0

Source: https://habr.com/ru/post/1729757/


All Articles