Reputation: 12438
I've been reading about xunit and I'm a bit confused how to use Theory.
Lets say I have this test:
[Theory]
[InlineData("")]
[InlineData("anything")]
public void AddItem_NoName_ThrowsNoNameException(string name)
{
// Arrange.
ItemService itemService = new ItemService();
Item item = new Item();
item.Name = name;
// Act.
Exception ex = Record.Exception(() => itemService.AddItem(item));
// Assert.
Assert.NotNull(ex);
Assert.IsType<NoNameException>(ex);
}
And the method under test:
public void AddItem(Item item)
{
if (item.Name == "")
throw new NoNameException();
_DAL.AddItem(item);
}
So this creates two unit tests: one passing an argument of empty string ("") and one the word "anything". So the first one (the empty string) passes since we have code that checks if item.Name is empty string, throw exception. The second one however, fails, because Assert.NotNull(ex) in the unit test will be false. However, if you look at the AddItem method, the method is correctly coded so what I want to see is both tests pass.
Maybe I'm wrong in how I implemented by unit test but what I want to happen or what I think should happen in this case is that both test should pass since the method under test is correct (based on the rules). How do I do this?
UPDATE:
OK, I've managed to make this both pass by doing the code below. However, I think that is not correct, to have conditional assertion. Still need help.
[Theory]
[InlineData("", false)]
[InlineData("anything", true)]
public void AddItem_NoName_ThrowsNoNameException(string name, isValid)
{
// Arrange.
ItemService itemService = new ItemService();
Item item = new Item();
item.Name = name;
// Act.
Exception ex = Record.Exception(() => itemService.AddItem(item));
// Assert.
if (!isValid)
{
Assert.NotNull(ex);
Assert.IsType<NoNameException>(ex);
}
else
{
Assert.Null(ex);
}
}
Upvotes: 5
Views: 10339
Reputation: 1323
These are two different test cases and should have individual tests written. Theory
should be used when the test code is the same.
[Theory]
[InlineData("")]
[InlineData(null)] // will fail based on your impl, just used for example
public void AddItem_NoName_ThrowsNoNameException(string name)
{
// Arrange
ItemService itemService = new ItemService();
Item item = new Item();
item.Name = name;
// Act & Assert
Assert.Throws<NoNameException>(() => itemService.AddItem(item));
}
[Fact]
public void AddItem_WithName_DoesXYZ()
{
// Arrange
ItemService itemService = new ItemService();
Item item = new Item();
item.Name = "anything";
// Act
itemService.AddItem(item);
// Assert
# verify item was added to db
}
Upvotes: 4