【发布时间】:2014-08-08 16:02:30
【问题描述】:
使用 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));
}
}
【问题讨论】:
-
你基本上看到了这个的含义:github.com/AutoFixture/AutoFixture/issues/176
-
@MarkSeemann 啊 tnx 开启了一种可能性。它可能适用于单一返回类型。我会测试它是否适用于多个。有没有办法让夹具用于自动数据?
-
你可以要求它作为方法参数...
-
@MarkSeemann 哇,谢谢!我没想到。明天我会研究它并在这个线程中添加一个可行的解决方案
标签: nunit autofixture automoq