I had to write a unit test for an existing method which maps an enum to another enum. This unit test is concerned about the scenario when the mapping is not defined in the method, and we get an exception in the default block of the switch statement.
enum players{sachin, ponting, mculum, gayle}
enum teams{westindies, australia, india, newzealand, southafrica}
public teams MappingMethod(players p)
{
switch(p)
{
case sachin: return india;
case gayle: return westindies;
......
default: throw new ArgumentOutOfRangeException();
}
}
I tried the unit test with ExpectedException attribute and the unit test worked fine when we had the above scenario. But it fails when the mapping exists for all the items in the enum.
To resole this, I had used a try..catch block inside the unit test and used Assert.IsInstanceOfType to check for the exception instead of using the ExpectedException attribute.
Is there any other better way to do this unit testing?
It seems what you want to achieve is a way to ensure that each item in the first enum should correspond to an item in the other. That is, you want MappingMethod
to always succeed. If this is the case, then I might suggest you might not need ExpectedException
at all. How about writing a test that iterates over all elements in Players
and call MappingMethod for each one? This test would fail if there are any players that aren't mapped.
In addition to this, you could write a test that checks that the expected exception is thrown when you get invalid data. Something like this:
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Throw_Exception_When_Mapping_Does_Not_Exist() {
MappingMethod((Players)-1);
}
Take this exact code with a pinch of salt - if I'm not mistaken, ((Players)-1)
will give you an object of type Players
that doesn't correspond to any element in the actual enum (unless, of course, you have assigned such a value). Thus, the call to MappingMethod
will certainly fail.
By the way, I would like to add, I'm not sure using enums are appropriate in yoru case. Generally, when enums force you to use some switch
statement, it's a code smell and you should consider instead changing the enum to a class. Enums are generally used to represent simple static and limited data. I suspect maybe Players
should be a class instead of an enum. Consider a structure like:
class Player {
public Teams Team { get; private set; }
public string Name { get; private set; }
public Player(string Name, Teams team) { /* set properties */ }
}
Then you would have a player sachin = new Player("Sachin", Teams.India)
. This ensures that each player is associated with a team. Furthermore, it is more dynamic as you can add more Players later, and you can add more statistics to each player, etc.
I hope this helps. Have a nice day :)