Search code examples
c#asp.net-corexunit

New to C#, having trouble with calculations with C# enums and casting


I'm new to C# and having some difficulty figuring out why my unit tests on this one function keep failing.

I have an enum (this is all examples, but you get the gist):

public enum TeamActions 
{
   TeamWasScoredAgainst = - 10,
   TeamScored = 10
}

I then have a static TeamHelper class which calculates a long of TeamScore on my Team object by evaluating whether or not the TeamAction is a positive value or not, so I know whether to add or subtract from the running TeamScore total.

public class Team
{
  public long TeamScore {get; set;}
}

public static long CalcNewTeamScore(Team team, TeamActions teamAction)
{
    if (team == null) throw new ArgumentNullException("Team is null");
    if ((int)teamAction < 1)
    {
       return team.TeamScore - Convert.ToInt64((int)teamAction);
    }
    else
    {
       return team.TeamScore + Convert.ToInt64((int)teamAction);
    }
}

My xUnit test, which fails is:

public void TeamWasScoredAgainst_ShouldDecreaseScore()
{
    // arrange
    var teamUnderTest = new Team
    {
      TeamScore = 100
    };

    // act
    teamUnderTest.TeamScore = TeamHelper.CalcNewTeamScore(teamUnderTest, TeamAction.TeamWasScoredAgainst);

    // assert
    Assert.Equal(90, teamUnderTest.TeamScore);
}

I'm really not sure if my test is wrong (first time doing it), or the TeamHelper method casts are wrong, or the math is wrong itself. Any help?


Solution

  • Your maths are wrong.

    Since your enum value itsself is already negative, subtracting it from something else, actually increases the result.

    You should change

    public static long CalcNewTeamScore(Team team, TeamActions teamAction)
    {
        if (team == null) throw new ArgumentNullException("Team is null");
        if ((int)teamAction < 1)
        {
           // Convert.ToInt64((int)teamAction) = -10
           // you actually have 100 - (-10) => 110
           return team.TeamScore - Convert.ToInt64((int)teamAction);
        }
        else
        {
           return team.TeamScore + Convert.ToInt64((int)teamAction);
        }
    }
    

    to

    public static long CalcNewTeamScore(Team team, TeamActions teamAction)
    {
        if (team == null) throw new ArgumentNullException("Team is null");    
        return team.TeamScore + Convert.ToInt64((int)teamAction);    
    }
    

    The problem in your code is that teamAction can be negative and you subtract negative values. If you subtract a negative value from a number, the result is higher than the number you subtracted from.

    A shorter sample to show the problem:

    var negativeValue = -10;
    var result = 10 - negativeValue;
    Assert.Equal(20, result);
    

    This is just like maths work in real world aswell.

    x = 10 - (-10)
    x = 10 + 10
    x = 20