检查ICollection是否实际为只读的正确方法

时间:2018-04-03 15:07:52

标签: c#

有我的模型类

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类型。

2 个答案:

答案 0 :(得分:10)

ICollection提供了一个名为IsReadOnly的属性,可让您检查您的集合实例是否为只读而不执行任何操作:

Assert.That(modelInstance.MyCollection.IsReadonly);

答案 1 :(得分:0)

dasblinkenlight直接回答了您的问题:使用IsReadOnly。你的另一个问题也很好:

  

将属性类型更改为ReadOnlyCollection<string>是实现所需行为的唯一解决方案吗?

它不是唯一的解决方案,但我认为它是最好的解决方案。

如果收集的是应该将您的属性声明为IReadOnlyCollection<string>。您的类或接口的API应该描述它们应该如何使用,并让我知道(作为代码的使用者)如何期望它们的行为。

例如,拥有IList<string>属性是一种糟糕的代码气味,但每当添加或删除项目时都会抛出异常。如果您要为只读集合建模,请明确并尽可能使用IReadOnlyCollection<string>

您的示例有点微妙,但是当您看到检查接口方法是否会抛出NotSupportedException之类的内容时,它是一个很好的提示,可以确保接口正确描述您的类的行为