【问题标题】:Mocking a class with private ctor and static create method and private id property使用私有 ctor 和静态创建方法和私有 id 属性模拟一个类
【发布时间】:2014-04-02 21:39:51
【问题描述】:

我正在尝试使用 AutoFixture 来简化我的生活。

我如何模拟一个类

  • 非公共构造函数和
  • 非公开 ID 和
  • 静态“创建”方法?

例子

public class User
{
    private User(){}

    /// <summary>
    ///     Created by Database...
    /// </summary>
    public long? Id { get; protected set; }

    public string Name { get; protected set; }

    public static User Create(string name)
    {
        var user = new User {Name = name};
        return user;
    }
}

我尝试过使用 Factory 和 SpecimenBuilder 的组合:

    [Fact]
    public void CreatingUserWithId_Should_Work_UsingFactoryAndSpecimenBuilder()
    {
        IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());
        fixture.Customizations.Add(new UserBuilder());
        fixture.Customize<User>(o => o.FromFactory(() => User.Create("foo")));

        var user = fixture.Create<User>();

        user.Should().NotBeNull();
        user.Id.Should().HaveValue();
    }

public class UserBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;
        if (pi == null) return new NoSpecimen(request);

        // The following code only works for public properties... :-(
        if (pi.Name == "Id" && pi.PropertyType == typeof (long?)) return 42;

        return new NoSpecimen(request);
    }
}

https://github.com/draptik/MockingStaticCreate 提供演示 C# 解决方案

感谢任何指点,

帕特里克

【问题讨论】:

  • 我认为你过于复杂了。您的静态方法只创建一个具有名称集的用户......只需验证它而不用模拟它。

标签: c# unit-testing mocking autofixture fakeiteasy


【解决方案1】:

AF 将做正确的事情(User.Create() 使用匿名名称 arg),无需任何自定义。

唯一缺少的位是设置Id。您必须自己回答哪个问题 - 您的消费代码首先应该如何做到这一点?当你决定了,你可以做fixture.Customize&lt;User&gt;( c =&gt; c.FromFactory( User.Create).Do( x =&gt; ???)

也许您可以考虑公开一个也采用id 的 ctor。然后你可以做一个Customize&lt;User&gt; ... GreedyConstructorQuery

如果您的 ORM 正在做一些古怪的反射,并且您喜欢它和/或无法绕过它,您可以选择是否应该进行测试:

a) 也这样做 - 如果这与给定的测试或一组测试相关

b) 认为这是可行的方法

关于将模拟和输入值混合到实体或值对象中 - 不要这样做(Mark Seemann's Commands vs Queries article 可能会帮助你)。您似乎需要/想要这样做的事实使您似乎在单个测试中过于雄心勃勃-您是否找到了最简单的测试方法并尝试使用单个 Assert 以最少的方式测试一件事设置。

去购买GOOS book - 它会帮助你找出平衡这些权衡的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-23
    • 2010-09-24
    • 1970-01-01
    • 2013-08-16
    • 2014-10-24
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多