nunit - AutoFixture/AutoMoq + NUnit AutoData 卡住对象未由 AutoMoq 接口(interface)方法返回

标签 nunit autofixture automoq

使用 AutoMoqCustomization 我本希望我的测试能成功,但它失败了。

这是测试:

[Test, AutoMoqData]
public void Test1(
    [Frozen] MyObject myObject, 
    [Frozen] Mock<IRepo> stubMock, 
    MyClass sut, 
    int objectId)
{
    myObject.Id = objectId;
    MyObject result = sut.GetById(objectId);
    Assert.That(result.Id, Is.EqualTo(myObject.Id));
}

如果我添加一行代码,我就能让它工作。但我不想这样做,因为它应该被推断出来??

    stubMock.Setup(r => r.GetObject(It.IsAny<int>())).Returns(() => myObject);

MyClass 有一个带有 IRepo 的构造函数。这就像一个魅力,因为如果我在我的测试中使用上面的行,我就通过了测试。

通常我在没有自动数据的情况下编写我的测试它会更加冗长:

[Test]
public void Test3()
{
    IFixture fixture = new Fixture();
    int objectId = fixture.Create<int>();
    var stubMock = fixture.Freeze<Mock<IRepo>>();

    stubMock.Setup(r => r.GetObject(It.IsAny<int>())).Returns(() => fixture.Create<MyObject>());
    fixture.Freeze<MyObject>(customise => customise.With(d => d.Id, objectId));

    var sut = new MyClass(stubMock.Object);
    MyObject result = sut.GetById(objectId);
    Assert.That(result.Id, Is.EqualTo(objectId));
}

所以我的代码已经干净多了,但就像上面的最后一颗樱桃一样 :) 有什么想法吗???

如何运行:

添加 Nuget 包:

<packages>
  <package id="AutoFixture" version="3.19.2" targetFramework="net45" />
  <package id="AutoFixture.AutoMoq" version="3.19.2" targetFramework="net45" />
  <package id="AutoFixture.NUnit2" version="3.19.2" targetFramework="net45" />
  <package id="Moq" version="3.1.416.3" targetFramework="net45" />
  <package id="NUnit" version="2.6.3" targetFramework="net45" />
</packages>

完整代码:

public class AutoMoqDataAttribute : AutoDataAttribute
    {
        public AutoMoqDataAttribute()
            : base(new Fixture().Customize(new AutoMoqCustomization()))
        {
        }
    }

    [TestFixture]
    public class Class1
    {
        public interface IRepo
        {
            MyObject GetObject(int id);
        }

        public class MyObject
        {
            public int Id { get; set; }
        }

        public class MyClass
        {
            private readonly IRepo _test;

            public MyClass(IRepo test) { _test = test; }

            public MyObject GetById(int id) { return _test.GetObject(id); }
        }

        [Test, AutoMoqData]
        public void Test1(
            [Frozen] MyObject myObject, [Frozen] IRepo stubMock, MyClass sut, int objectId)
        {
            myObject.Id = objectId;

            // expecting this commented line to be automatic because of the Frozen attribute on myObject? 
            // Mock.Get(stubMock).Setup(r => r.GetObject(It.IsAny<int>())).Returns(() => myObject);

            MyObject result = sut.GetById(objectId);

            Assert.That(result.Id, Is.EqualTo(myObject.Id));
        }

        [Test, AutoMoqData]
        public void Test2(
            [Frozen] MyObject myObject, [Frozen] Mock<IRepo> stubMock, MyClass sut, int objectId)
        {
            myObject.Id = objectId;

            // expecting this commented line to be automatic because of the Frozen attribute on myObject? 
            // stubMock.Setup(r => r.GetObject(It.IsAny<int>())).Returns(() => myObject);

            MyObject result = sut.GetById(objectId);

            Assert.That(result.Id, Is.EqualTo(myObject.Id));
        }

        [Test]
        public void Test3()
        {
            IFixture fixture = new Fixture();
            int objectId = fixture.Create<int>();
            var stubMock = fixture.Freeze<Mock<IRepo>>();

            stubMock.Setup(r => r.GetObject(It.IsAny<int>())).Returns(() => fixture.Create<MyObject>());
            fixture.Freeze<MyObject>(customise => customise.With(d => d.Id, objectId));

            var sut = new MyClass(stubMock.Object);
            MyObject result = sut.GetById(objectId);
            Assert.That(result.Id, Is.EqualTo(objectId));
        }

    }

最佳答案

从 3.20.0 开始,您可以使用 AutoConfiguredMoqCustomization。这将自动配置所有模拟,以便其成员的返回值由 AutoFixture 生成。

虚拟方法/属性/索引器将被设置为使用 AutoFixture 延迟生成它们的返回值。如果该方法有 out 参数,这些参数也将被设置。

公共(public)字段和密封属性将立即设置它们的值。

这个测试现在应该通过了:

[Test, AutoMoqData]
public void Test1(
    [Frozen] MyObject myObject,
    MyClass sut,
    int objectId)
{
    myObject.Id = objectId;
    MyObject result = sut.GetById(objectId);
    Assert.That(result.Id, Is.EqualTo(myObject.Id));
}

关于nunit - AutoFixture/AutoMoq + NUnit AutoData 卡住对象未由 AutoMoq 接口(interface)方法返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25207585/

相关文章:

c# - NUnit DLL 版本不匹配

c# - 如何将 AutoDataAttribute 与 InlineData 结合使用

c# - 如何使用 Autofixture 中的 RandomRangedNumberCustomization 来确保参数在一定范围内?

c# - 使用 AutoFixture 自定义显式设置样本的多个属性

unit-testing - 可以卡住函数的模拟吗?

c# - 带有 NUnit 的 SpecFlow : SetUp method runs twice

c# - 如何对自定义 JsonConverter 进行单元测试

c# - 如果我想对以表达式作为参数的方法进行单元测试,我应该更改什么?

c# - NUnit测试调试

c# - AutoFixture 无法创建匿名 MVC Controller