3

使用这种结构。

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始终是“史密斯”(字面意思)
  3. 确保User.MiddleName未填充(默认)
  4. 确保 User.IsAdministrator() 返回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:创建一个具有填充属性和模拟方法的对象。

4

1 回答 1

3

以下实现了所要求的目标

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>();

但是,如果您要显式设置成员返回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();

有效。

这是测试的另一种变体,其主题类取决于要注入的模型。

[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();
}
于 2020-11-17T18:32:23.630 回答