Правильное использование теории в 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 
}
Другие вопросы по тегам