Question

I'm getting some odd behavior in a test I'm writing using FluentAssertions. I have the following class:

public class Die
{
     Random rand;

     public Die()
     {
       rand = new Random();
     }

     public Symbol Roll()
     {
       var symbols = Enum.GetValues(typeof(Symbol));
       return (Symbol)symbols.GetValue(rand.Next(symbols.Length));
     }
}

public enum Symbol
{
  Success,
  Failure
}

I want to do some quick sanity checking that I'm actually creating a die which returns a random value, and not always the same value. So my "quick and dirty" for TDD was to roll it 100 times and assume that it at least generates both values once. However, I noticed when I dropped the number lower (to 10) I was getting some failures I didn't expect. Dropping it to 2 looked like this:

[TestMethod]
public void Test_Die_Roll_Returns_Multiple_Values()
{
  Die die = new Die();

  Enumerable.Range(1, 2)
    .Select((x) => die.Roll()).Should().Contain(Symbol.Success);
}

Sometimes when I run this test, it passes. Sometimes, it fails, of course when the collection is {Failure,Failure}. This is expected. However, sometimes it fails with a message like this:

Message: ExpectedCollection {Success, Failure} to contain Success.

What on earth is going on here? I did some digging and found a lot of stuff about Contains using reference equals instead of value equals. Wanting to move on, I tried this:

[TestMethod]
public void Test_Die_Roll_Returns_Multiple_Values()
{
  Die die = new Die();

  Enumerable.Range(1, 2)
    .Select((x) => die.Roll()).Should().Contain(s => s.ToString().Equals("Success"));
}

Only to sometimes get a pass, and sometimes get:

Message: Collection {Success, Failure} should have an item matching s.ToString().Equals("Success").

What's going on?

Was it helpful?

Solution

Since you're Roll() method is returning random numbers, you're test is already quite brittle. It might be just a result of that randomness. Passing an expression tree into a method that takes an IEnumerable is a bad practice and the source of many errors. Always call ToList() or ToArray() first (though the former is a bit faster) .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top