使用私有设置器测试属性
Testing properties with private setters
目前在我项目的一部分中存在如下域对象:
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; }
}
地区 属性 是数据库中的计算列。由于数据访问提供者 (Entity Framework) 的要求,需要一个私有集。这在正常程序流程中很好,因为不需要设置 District,因为它会在数据库中的地址记录为 saved/updated
时更新
我想测试的方法如下所示:
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 属性,因此我无法编写测试来检查是否返回了正确的匹配地址。
我应该如何为这个测试设置地址对象?
首先,大胆猜测:可能是将 District
属性 声明为 protected internal
加上向 "domain" 程序集添加 assembly:InternalsVisibleTo
属性的组合这样 Distinct
就可以从你的测试中设置。
class Address
{
public virtual string District { get; protected internal set; }
}
或者,您可以向 Address
class 添加一个内部构造函数,这将设置 District
属性 的值。再次,用 assembly:InternalsVisibleTo
.
注释您的 "domain" 程序集
如果您使用的是最小起订量(问题已标记,所以我假设您是),这可以立即使用:
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
目前在我项目的一部分中存在如下域对象:
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; }
}
地区 属性 是数据库中的计算列。由于数据访问提供者 (Entity Framework) 的要求,需要一个私有集。这在正常程序流程中很好,因为不需要设置 District,因为它会在数据库中的地址记录为 saved/updated
时更新我想测试的方法如下所示:
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 属性,因此我无法编写测试来检查是否返回了正确的匹配地址。
我应该如何为这个测试设置地址对象?
首先,大胆猜测:可能是将 District
属性 声明为 protected internal
加上向 "domain" 程序集添加 assembly:InternalsVisibleTo
属性的组合这样 Distinct
就可以从你的测试中设置。
class Address
{
public virtual string District { get; protected internal set; }
}
或者,您可以向 Address
class 添加一个内部构造函数,这将设置 District
属性 的值。再次,用 assembly:InternalsVisibleTo
.
如果您使用的是最小起订量(问题已标记,所以我假设您是),这可以立即使用:
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