【发布时间】:2014-06-23 09:21:39
【问题描述】:
我正在为一个管理标签对象树的类编写测试:
public class Tag
{
public virtual int Id { get; set; }
public virtual string Description{ get; set; }
private IList<Tag> children = new List<Tag>();
public virtual IEnumerable<Tag> Children
{
get {return children .ToArray();}
}
public void AddChildTag(Tag child)
{
children.Add(child);
}
public void RemoveChildTag(Tag child)
{
children.Remove(child);
}
}
如您所见,设置父属性的唯一模式是通过 AddChildTag 方法,这正是我想要的,我的问题在于单元测试:因为每个测试都应该是原子的,我如何测试 @ 987654323@方法?
我看到的唯一方法是调用 add 方法,然后调用 remove,但是这样如果 Add 作为一些错误,即使 remove 测试也会失败,因此原子性丢失。
如何做到这一点?
编辑
我从 Tag 对象中删除了父属性,因为我不再使用它
根据使用 NUnit 和 FluentAssertion 的解决方案进行一些测试
[Test]
public void AddChildTagAddsChildren()
{
//Arrange
Tag parent = new Tag();
Tag child = new Tag();
//Act
parent.AddChildTag(child);
//Assert
parent.Children.Should().Contain(child);
}
[Test]
public void RemoveChildTagRemovesAddedChildren()
{
//Arrange
Tag parent = new Tag();
Tag child = new Tag();
parent.AddChildTag(child);
//Act
parent.RemoveChildTag(child);
//Assert
parent.Children.Should().NotContain(child);
}
[Test]
public void RemoveChildTagThrowsNothingWhenNoChild()
{
//Arrange
Tag parent= new Tag();
Tag child= new Tag();
//Act
Action RemoveChild = () => parent.RemoveChildTag(child);
//Assert
RemoveChild.ShouldNotThrow();
}
【问题讨论】:
-
轻微的旁注:在不调用
Add的情况下调用Remove的行为也值得测试,以测试是否没有抛出异常或以正确的状态抛出正确的异常。 -
因为 remove 依赖于
add,如果测试通过了你就知道if add works, then remove works。一旦add被测试,你就会知道remove有效。 -
@Jonny,请看我对 Lukazoid 答案的评论
-
问题更新了一些测试
-
您的测试看起来不错。对于 Fluent,我建议为
act操作变量提供更多上下文名称(act.ShouldNotThrow()与removeChildTag.ShouldNotThrow())。
标签: c# unit-testing tdd