将 AutoFixture 与最小起订量一起使用?

Using AutoFixture with Moq?

使用这个结构。

public class User
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public virtual bool IsAdministrator()
    {
        return false;
    }
}

是否可以组合 AutoFixtureMoq 来完成以下操作?

  1. 确保 User.FirstName 是自动生成的
  2. 确保 User.LastName 始终是“Smith”(字面意思)
  3. 确保 User.MiddleName 未填充(默认)
  4. 确保User.IsAdministrator() returns True
  5. 验证调用了 IsAdministrator()

我知道这看起来很简单。这是我尝试使用 AutoMoq.

var config = new AutoMoqCustomization() 
{ 
    ConfigureMembers = true 
};

var fixture = new AutoFixture.Fixture();
fixture.Customize(config);

fixture.Freeze<Mock<User>>()
    .Setup(x => x.IsAdministrator())
    .Returns(true);

var model = fixture.Build<User>()
    .With(x => x.LastName, "Smith")
    .Without(x => x.MiddleName)
    .Create();

但这显然是错误的。 :( 我确信语法很简单。感谢您的帮助。

My goal:创建一个同时具有填充属性和模拟方法的对象。

以下实现了要求的目标

public void AutoFixture_Should_Fill_Poperties_And_Mock_Methods() {
    //Arrange
    AutoMoqCustomization config = new AutoMoqCustomization() {
        ConfigureMembers = true
    };

    IFixture fixture = new AutoFixture.Fixture().Customize(config);

    Mock<User> mock = new Mock<User>();
    mock
        .Setup(x => x.IsAdministrator())
        .Returns(true);

    User model = fixture.Build<User>()
        .FromSeed(s => mock.Object) //<-- 
        .With(x => x.LastName, "Smith")
        .Without(x => x.MiddleName)
        .Create();

    //Assert

    //Ensure User.FirstName is auto-generated
    model.FirstName.Should().NotBeNullOrEmpty();
    //Ensure User.LastName is always "Smith" (literal)
    model.LastName.Should().Be("Smith");
    //Ensure User.MiddleName is not populated (default)
    model.MiddleName.Should().BeNull();
    //Ensure User.IsAdministrator() returns True
    model.IsAdministrator().Should().BeTrue();
    //Verify IsAdministrator() was called.
    mock.Verify(_ => _.IsAdministrator());
}

一个观察结果是当使用

Mock<User> mock = fixture.Freeze<Mock<User>>();

if 仍会填充 MiddleName 属性,即使它被明确告知 Without 用于构建,但在使用

时按预期工作
Mock<User> mock = new Mock<User>();

但是,如果您明确将成员设置为 return null

Mock<User> mock = fixture.Freeze<Mock<User>>(); // new Mock<User>();
mock
    .Setup(x => x.IsAdministrator())
    .Returns(true);

User model = fixture.Build<User>()
    .FromSeed(s => mock.Object)
    .With(x => x.LastName, "Smith")
    .With(x => x.MiddleName, (string)null) //<--
    .Create();

成功了。

这是测试的另一个变体 class 取决于要注入的模型。

[Test]
public void AutoFixture_Should_Fill_Poperties_And_Mock_Methods() {
    //Arrange
    AutoMoqCustomization config = new AutoMoqCustomization() {
        ConfigureMembers = true
    };

    IFixture fixture = new AutoFixture.Fixture().Customize(config);

    Mock<User> mock = new Mock<User>();
    mock
        .Setup(x => x.IsAdministrator())
        .Returns(true);

    User model = fixture.Freeze<User>(c => c
        .FromSeed(s => mock.Object)
        .With(x => x.LastName, "Smith")
        .With(x => x.MiddleName, (string)null)
    );

    //Act
    Subject subject = fixture.Create<Subject>();
    bool actual = subject.Act();

    //Assert

    //Ensure User.FirstName is auto-generated
    model.FirstName.Should().NotBeNullOrEmpty();
    //Ensure User.LastName is always "Smith" (literal)
    model.LastName.Should().Be("Smith");
    //Ensure User.MiddleName is not populated (default)
    model.MiddleName.Should().BeNull();
    //Ensure User.IsAdministrator() returns True
    actual.Should().BeTrue();
    //model.IsAdministrator().Should().BeTrue();
    //Verify IsAdministrator() was called.
    mock.Verify(_ => _.IsAdministrator());
}


public class Subject {
    private User model;

    public Subject(User model) {
        this.model = model;
    }

    public bool Act() => model.IsAdministrator();
}