【问题标题】:Using AutoFixture with Moq?将 AutoFixture 与 Moq 一起使用?
【发布时间】:2020-11-17 16:33:15
【问题描述】:

使用这种结构。

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() 返回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:创建一个同时具有填充属性和模拟方法的对象。

【问题讨论】:

    标签: c# moq autofixture automoq


    【解决方案1】:

    以下实现了要求的目标

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

    【讨论】:

    • 不知何故我忽略了FromSeed()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多