有我的模型类
public class Model
{
public ICollection<string> MyCollection { get; }
}
我想测试MyCollection
getter返回实际只读集合。也就是说,类的客户端根本不能添加或删除元素。编写此类测试的正确方法是什么?
选项1
Assert.That(modelInstance.MyCollection is IReadonlyCollection<string>);
它返回true,例如MyCollection
属性的字段是List<string>
的实例(它实现IReadonlyCollection<string>
)。
选项2
var testDelegate = () => modelInstance.MyCollection.Add("QWERTY");
Assert.That(testDelegate, Throws.TypeOf<NotSupportedException>());
我发现它不优雅,因为可能有其他方法来修改返回的集合(例如List<string>
的索引器)
将属性类型更改为ReadOnlyCollection<string>
是实现所需行为的唯一解决方案吗?在这种情况下,我确实需要任何单元测试,但它更具体MyCollection
类型。
答案 0 :(得分:10)
ICollection
提供了一个名为IsReadOnly
的属性,可让您检查您的集合实例是否为只读而不执行任何操作:
Assert.That(modelInstance.MyCollection.IsReadonly);
答案 1 :(得分:0)
dasblinkenlight直接回答了您的问题:使用IsReadOnly
。你的另一个问题也很好:
将属性类型更改为
ReadOnlyCollection<string>
是实现所需行为的唯一解决方案吗?
它不是唯一的解决方案,但我认为它是最好的解决方案。
如果收集的是,应该将您的属性声明为IReadOnlyCollection<string>
。您的类或接口的API应该描述它们应该如何使用,并让我知道(作为代码的使用者)如何期望它们的行为。
例如,拥有IList<string>
属性是一种糟糕的代码气味,但每当添加或删除项目时都会抛出异常。如果您要为只读集合建模,请明确并尽可能使用IReadOnlyCollection<string>
。
您的示例有点微妙,但是当您看到检查接口方法是否会抛出NotSupportedException
之类的内容时,它是一个很好的提示,可以确保接口正确描述您的类的行为