【问题标题】:FakeItEasy deep nested types fakingFakeItEasy 深嵌套类型伪造
【发布时间】:2013-01-17 15:38:11
【问题描述】:

我有一个想要伪造的复杂对象。

interface IContext
{
    User User { get; }
}

A.CallTo(
    () => _fakeContext.User.Subscription.Attributes)
    .Returns(new List<Attribute>());

但我得到了下一个例外:

The current proxy generator can not intercept the specified method for the following reasons: - Non virtual methods can not be intercepted

所有嵌套类型都是属性,它们是带有get; set; 属性修饰符的简单贫血类型。当我查看调试器时,它们都是假的。

有什么方法可以设置链的最后一个属性,避免设置之前的所有属性?

【问题讨论】:

  • User 上的属性是虚拟的吗?如果是这样,您可以发布User 的源代码吗?
  • 没有。用户和订阅都不是虚拟的。它是来自已编译程序集的代码。
  • FakeItEasy 无法模拟非虚拟方法,因此您必须自己解决构建对象。像下面的答案一样可以解决问题。

标签: unit-testing mocking fakeiteasy


【解决方案1】:

如果您的对象足够贫血,您可能想试试AutoFixture

var fake = A.Fake<>();
var fixture = new Fixture();
// If it's possible [1], AutoFixture will generate entire object graph
var user = fixture.CreateAnonymous<User>();
// Since data will be random [2], you can overwrite properties as you like
user.User.Subscription.Attributes = new List<Attributes>();
A.CallTo(() => fake.User).Returns(user);
  1. 为了使其工作,您的自定义对象需要具有公共构造函数,并且最好避免使用接口(但这可以通过 auto-mocking 扩展来缓解,例如 AutoFakeItEasy)。
  2. .Build 方法提供了流畅的 API 来自定义对象自动生成,因此可以控制随机性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多