我一直在阅读有关xunit的内容,我对如何使用Theory感到有些困惑。
让我说我有这个测试:
[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);
}
所以这会创建两个单元测试:一个传递空字符串的参数(&#34;&#34;),另一个传递#34;任何&#34;。所以第一个(空字符串)通过,因为我们有代码检查item.Name是否为空字符串,抛出异常。然而,第二个失败,因为单元测试中的Assert.NotNull(ex)将为false。但是,如果你看一下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);
}
}
答案 0 :(得分: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
}