Правильное использование теории в xUnit
Я читал о Xunit, и я немного запутался, как использовать Теорию.
Допустим, у меня есть этот тест:
[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);
}
И тестируемый метод:
public void AddItem(Item item)
{
if (item.Name == "")
throw new NoNameException();
_DAL.AddItem(item);
}
Таким образом, это создает два модульных теста: один передает аргумент пустой строки ("") и один слово "что-нибудь". Таким образом, первая (пустая строка) проходит, так как у нас есть код, который проверяет, является ли item.Name пустой строкой, генерируем исключение. Второй, однако, терпит неудачу, потому что Assert.NotNull(ex) в модульном тесте будет ложным. Однако, если вы посмотрите на метод AddItem, он правильно закодирован, поэтому я хочу увидеть, как оба теста пройдены.
Возможно, я ошибаюсь в том, как я реализовал модульное тестирование, но то, что я хочу, или то, что я думаю, должно произойти в этом случае, состоит в том, что оба теста должны пройти, так как тестируемый метод является правильным (на основе правил). Как мне это сделать?
ОБНОВИТЬ:
Хорошо, мне удалось сделать это, выполнив код ниже. Однако я считаю, что это неправильно, иметь условное утверждение. Все еще нужна помощь.
[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);
}
}
1 ответ
Это два разных тестовых случая и должны быть написаны отдельные тесты. Theory
должен использоваться, когда тестовый код тот же.
[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
}