C# TDD-由于安排阶段的假设而导致单元测试失败
我正在做(或试图做)TDD来开发应用程序的业务逻辑 我在一个类中有一个集合,我将其公开为C# TDD-由于安排阶段的假设而导致单元测试失败,c#,unit-testing,testing,nunit,tdd,C#,Unit Testing,Testing,Nunit,Tdd,我正在做(或试图做)TDD来开发应用程序的业务逻辑 我在一个类中有一个集合,我将其公开为IReadOnlyList,因为我想明确指出,禁止从列表中添加/删除。相反,我公开了AddItem和removietem方法,以便在添加或删除项时可以执行一些其他代码。见下面的例子 public interface IBusinessItem { } public interface IBusinessClass { IReadOnlyList<IBusinessItem> Items {
IReadOnlyList
,因为我想明确指出,禁止从列表中添加/删除。相反,我公开了AddItem
和removietem
方法,以便在添加或删除项时可以执行一些其他代码。见下面的例子
public interface IBusinessItem { }
public interface IBusinessClass
{
IReadOnlyList<IBusinessItem> Items { get; }
void AddItem(IBusinessItem item);
void RemoveItem(IBusinessItem item);
}
我认为如果我可以访问sut.Items.Add(item)
,而不是依赖sut.AddItem(item)
,那么我的单元测试就不会那么脆弱了,但我不想这样做
我认为这部分解决了我的担忧。我对答案的解释(以及其中一个作者对答案的评论)是,在排列阶段调用其他方法是可以的。但我觉得这可能会导致很多测试失败,除了他们实际测试的原因
我的问题是:在执行TDD时,是否可以访问底层的列表。添加(这不是我的公共界面的一部分),以避免依赖我的removietem
测试中的添加项
实现
我可以想出几种方法来访问基础列表。添加:
- 在测试中铸造它
- 将底层private字段更改为protected,并创建从my BusinessClass继承并公开该字段的mock
- 将基础私有字段更改为内部,并使用
InternalsVisibleTo
属性
如果要公开某些内容,只需创建一个模拟、存根。。。它从基本类继承的版本。继承的版本可能会公开您想要的内容。不需要InternalsVisibleTo。我建议添加一个专门用于接受一组项的测试的构造函数。在构造函数中,直接初始化基础集合,而不调用AddItem。这样,您的安排阶段将不依赖于AddItem。
[Fact]
public void RemoveItemShouldRemoveItemFromItems()
{
// Arrange
var item = new MyBusinessItem();
sut.AddItem(item);
// Act
sut.RemoveItem(item); // throws exception if sut.Items is empty
// Assert
Assert.Empty(sut.Items);
}