使用私有setter测试属性

时间:2016-04-29 12:45:33

标签: c# unit-testing moq encapsulation access-modifiers

目前在我的项目的一部分中存在如下的域对象:

public class Address
{
    public virtual string HouseName { get; set; }

    public virtual string HouseNumber { get; set; }

    public virtual string RoadName { get; set; }

    public virtual string Postcode { get; set; }

    public virtual string District { get; private set; }
}

区属性是数据库中的计算列。由于数据访问提供程序(实体框架)的要求,需要私有集。这在正常的程序流程中很好,因为区域永远不需要设置,因为在数据库中保存/更新地址记录时它会被更新

我想测试的方法如下所示:

public IEnumerable<House> GetHousesWithinSameDistrict (int addressId)
{
    var addressToMatch = _addressRepository
      .FirstOrDefault(address => address.Id == addressId)

    return _houseRepository
      .Where(house => house.Address.District == addressToMatch.District)
}

当我尝试设置addressToMatch变量时,这会导致我出现问题,因为我无法设置District属性,因此我无法编写测试来检查是否返回了正确的匹配地址。

我该如何设置此测试的Address对象?

2 个答案:

答案 0 :(得分:7)

如果你正在使用Moq(问题标记为,所以我认为你是),这是开箱即用的:

var mockAddress = new Mock<Address>();
mockAddress.SetupGet(p => p.District).Returns("Whatever you want to match");

所以更完整的例子是:

var mockAddress = new Mock<Address>();
mockAddress.SetupGet(p => p.Id).Returns(42);
mockAddress.SetupGet(p => p.District).Returns("What you want to match");

var mockAddressRepository = new Mock<IRepository<Address>>();
var addresses = new List<Address> { mockAddress.Object };
mockAddressRepository.Setup(p => p.GetEnumerator()).Returns(addresses.GetEnumerator());

var addressToMatch = mockAddressRepository.Object.FirstOrDefault(address => address.Id == 42);
Console.WriteLine(addressToMatch.District);

输出预期值:

What you want to match

答案 1 :(得分:1)

首先,一个疯狂的猜测:可能是将District属性声明为protected internal并将assembly:InternalsVisibleTo属性添加到“域”程序集中,以便Distinct可以从你的测试中设定。

class Address
{
    public virtual string District { get; protected internal set; }
}

或者,您可以向Address类添加内部构造函数,该类将设置District属性的值。再次,使用assembly:InternalsVisibleTo注释您的“域名”程序集。