题
创建假货时如何处理只读字段?
背景
我正处于使用 ASP.Net MVC 的初级阶段,并以 Steven Sanderson 的 Sports Store 和 Scott Gu 的 Nerd Dinner 为例。我刚刚遇到的一个小问题是在做假货时如何使用只读属性。我正在使用 LINQToSQL。
我的界面是:
public interface IPersonRespository
{
Person GetPerson(int id);
}
而我的假货变成了
public class FakePersonRepository
{
public Person GetPerson(int id)
{
return new Person {id="EMP12345", name="John Doe", age=47, ssn=123-45-6789, totalDrWhoEpisodesWatched=42};
}
}
这是我的问题。字段 id、ssn 和 totalDrWhoEpisodesWatched 是只读的,因此上面的代码实际上不起作用。但是,我不知道如何创建一个假的新人并设置只读属性。我确定有一个解决方案,但我还没有在搜索中遇到它。
更新:继承 + 属性隐藏作为一个潜在的解决方案?
我还没有决定对这个问题有一个坚定的解决方案。我不喜欢为了创建假货而修改我的域类的想法。对我来说,向域类添加标记以进行测试是一种添加耦合的形式——耦合到测试的实现。我现在正在研究另一种可能性,即创建一个 FakePerson 类,该类继承自 Person,但使用新的读写属性隐藏属性。
public class FakePerson: Person
{
public new int age { get; set; }
public new string ssn { get; set; }
public new int totalDrWhoEpisodesWatched { get; set; }
}
到目前为止,这个解决方案是我的倾向。它确实违反了 Liskov 替换原则,但是在测试项目中这并没有给我带来太多麻烦。作为解决方案,我很高兴听到对此的任何批评和/或反馈。
获胜者:模拟框架
Moq 似乎可以完成这项工作。我最后一个通过继承隐藏属性的解决方案确实有效,但是通过使用 Moq,我获得了一组更易于维护的标准化功能。我假设其他模拟框架具有此功能,但我没有检查过。据说 Moq 对于开始模拟写作更直接,我现在绝对是这样。
最佳答案
考虑在测试中模拟 Person 类型。使用 Moq 的示例:
var mock = new Mock<Person>();
mock.SetupGet(p => p.id).Returns("EMP12345");
mock.SetupGet(p => p.ssn).Returns("123-45-6789");
mock.SetupGet(p => p.totalDrWhoEpisodesWatched).Returns(42);
return mock.Object;
否则,尝试找出 LINQ to SQL 如何设置这些只读属性。
编辑 :如果您尝试上述操作并且 Moq 抛出
ArgumentException
在 SetupGet
留言联系 “不可覆盖成员上的无效设置:p => p.id” ,那么您需要将该属性标记为 虚拟 .这将需要为您希望覆盖其 getter 的每个属性完成。在 LINQ to SQL 中,这可以通过选择属性在 OR 设计器中完成,然后在属性窗口中设置 继承修饰符 至 虚拟 .
关于asp.net-mvc - 在 TDD 和 DDD 中,您如何处理假货中的只读属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/965539/