单元测试基类中的存根保护列表
本文关键字:保护 列表 存根 基类 单元测试 | 更新日期: 2023-09-27 18:26:49
我想测试一个方法是否将对象添加到基类中的列表中。
我的问题是这个列表是受保护的,所以我不能在我的测试安排中填充它。因此,列表是空的,并且我的方法无法在特定索引处添加对象。
如何制作一个存根列表,并在不公开的情况下使用它来代替真正的基类列表?
我使用NUnit和Moq。
这里有一些代码来模仿我的问题:
public class Person
{
public string Name { get; set; }
readonly List<PhoneNumber> _numbers = new List<PhoneNumber>();
public void AddNumber(PhoneNumber phoneNumber)
{
_numbers.Add(phoneNumber);
}
}
public class PhoneNumber
{
public int Number { get; set; }
}
public class BaseClass
{
protected List<Person> Persons = new List<Person>();
}
public class DerivedClass : BaseClass
{
public void AddNumberToPersons(int index, PhoneNumber phoneNumber)
{
Persons[index].AddNumber(phoneNumber); // <-- Need to test if
// this gets called without errors
}
}
[Test]
public void AddNumberToPersons_WhenAddingNumberToPersons_NumberGetsAddedToList()
{
// I think I need to use a stub list or else the list is empty
// and index is out of range.
// Assert that number is added to the list.
}
评论中有一些很好的讨论,讨论了为什么你可能想考虑你要测试的是什么。也就是说,在某些情况下,您可能确实希望设置类以使用其基类进行测试。在这种情况下,我倾向于使用该类的手动可测试版本,而不是使用Moq。因此,在您的测试项目中,如果您可以创建DerivedClass
的可测试版本,如下所示:
public class TestableDerived : DerivedClass {
public TestableDerived(List<Person> people) {
this.Persons = people;
}
public List<Person> AccessablePersons { get { return this.Persons; } }
}
TestableDerived
类可以访问层次结构的protected
成员,因此您可以在测试的排列部分填充它。通常情况下,您可以验证相应Person
的状态是否已更新以添加数字。这可能会给你一个类似这样的测试:
var sut = new TestableDerived(new List<Person>(){new Person(), new Person()});
sut.AddNumberToPersons(1, new PhoneNumber { Number = 1234 });
Assert.AreEqual(1, sut.AccessablePersons[1].Numbers.Where(x=>x.Number == 1234).Count());
然而,在您的特定示例中,这将不起作用,因为一旦添加了PhoneNumbers,Person
类就无法访问它们。有一些方法可以解决这个问题,但这似乎不是问题的重点,所以我选择相信这是示例代码中的一个遗漏,并添加了一个Numbers
访问器。