AutoFixture作为Automocking容器与Automocking差异?

cho*_*bo2 12 .net c# moq autofixture automocking

我开始使用moq但是根据我的理解,我总是要模拟所有可以调用的方法,即使我真的不关心它们.

有时需要很长时间来模拟你忘记你想做什么的东西.所以我一直在看自动模拟,但我不确定我应该使用什么.

AutoFixture作为自动模拟容器

Automocking

我根本不知道如何使用第一个.我有点得到第二个但从未真正尝试过.

我不确定一个人是否比另一个好.我唯一知道的是我使用AutoFixtures已经是第一个的依赖.

所以也许从长远来看,与第一个一起使用是有意义的,但就像我说我找不到任何关于如何使用它的基本教程.

编辑

我试图按照"Nikos Baxevanis"的例子,但我遇到了错误.

Failure: System.ArgumentException : A matching constructor for the given arguments was not found on the mocked type.
  ----> System.MissingMethodException : Constructor on type 'DatabaseProxyded46c36c8524889972231ef23659a72' not found.


var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var fooMock = fixture.Freeze<Mock<IFoo>>();
       // fooMock.Setup(x => x.GetAccounts(It.IsAny<IUnitOfWork>()));
        var sut = fixture.CreateAnonymous<AdminService>();

        sut.Apply();
        fooMock.VerifyAll();
Run Code Online (Sandbox Code Playgroud)

我认为这是因为我的petapoco unitOfWork财产

PetaPoco.Database Db { get; }
Run Code Online (Sandbox Code Playgroud)

不确定我是否要以某种方式嘲笑这个或什么.

Nik*_*nis 25

虽然我从未使用过moq-contrib Automocking,但我可能会提供一些有关使用AutoFixture作为自动模拟容器的信息.

目前支持Moq,Rhino Mocks,FakeItEasy和NSubstitute.只需安装相应的扩展名AutoMoq,AutoRhinoMocks,AutoFakeItEasyAutoNSubstitute即可.

一旦安装了Auto Mocking的一个扩展,额外的调用是:

var fixture = new Fixture()
    .Customize(new AutoMoqCustomization());
Run Code Online (Sandbox Code Playgroud)

(或者如果你使用的是Rhino Mocks)

var fixture = new Fixture()
     .Customize(new AutoRhinoMockCustomization());
Run Code Online (Sandbox Code Playgroud)

(或者如果你使用的是FakeItEasy)

var fixture = new Fixture()
     .Customize(new AutoFakeItEasyCustomization());
Run Code Online (Sandbox Code Playgroud)

(或者如果你使用的是NSubstitute)

var fixture = new Fixture()
     .Customize(new AutoNSubstituteCustomization());
Run Code Online (Sandbox Code Playgroud)

例1

public class MyController : IController
{
    public MyController(IFoo foo)
    {
    }
}

public interface IFoo
{
}
Run Code Online (Sandbox Code Playgroud)

以下是如何使用AutoFixture创建MyController类的实例:

var fixture = new Fixture()
    .Customize(new AutoMoqCustomization());

var sut = fixture.CreateAnonymous<MyController>();
Run Code Online (Sandbox Code Playgroud)

现在,如果你检查sut变量,你会看到它IFoo是一个模拟实例(类型名称类似于Castle.Proxies.IFooProxy).

例2

这个例子扩展了前一个例子.

您可以指示AutoFixture使用您自己的,预先配置的模拟实例:

var fooMock = fixture.Freeze<Mock<IFoo>>();
// At this point you may setup expectation(s) on the fooMock.

var sut = fixture.CreateAnonymous<MyController>();
// This instance now uses the already created fooMock.
// Verify any expectation(s).
Run Code Online (Sandbox Code Playgroud)

这基本上就是它 - 但它可以更进一步!

下面是使用AutoFixture前面的例子decleratively与xUnit.net 扩展.

例1

[Theory, AutoMoqData]
public void TestMethod(MyController sut)
{
    // Start using the sut instance directly.
}
Run Code Online (Sandbox Code Playgroud)

例2

[Theory, AutoMoqData]
public void TestMethod([Frozen]Mock<IFoo> fooMock, MyController sut)
{
   // At this point you may setup expectation(s) on the fooMock.
   // The sut instance now uses the already created fooMock.
   // Verify any expectation(s).
}
Run Code Online (Sandbox Code Playgroud)

您可以在博客文章中找到更多信息,其中包含与AutoFixture,xUnit.net和Auto Mocking相关的所有相关内容的链接.

希望有所帮助.

  • 在"示例1"中,我们并不关心在`IFoo`模拟上设置期望.我们继续请求AutoFixture创建一个`MyController`类型的实例.这将自动注入一个"IFoo"类型的模拟实例.在`Example 2`上,我们*想要设置和期望,所以我们手动创建一个模拟实例,我们_Freeze_它 - 告诉AutoFixture在请求`MyController`类型时_reuse_已经创建的实例.(如果我们不这样做,期望会失败,因为`MyController`将使用另一个实例 - 而不是我们设置期望的实例.) (3认同)
  • 是的,这是预期的,因为首先你请求了'MyController`类型(所以AutoFixture为`IFoo`依赖提供了一个自动模拟的实例),并在你创建了`IFoo`的一个_new_模拟后(这是一个不同的实例)那是在'MyController`中传递的.当你需要在模拟_Freeze_上设置期望它_before_你请求一个依赖于模拟对象的类型.这样,AutoFixture将_reuse_已经创建的模拟,期望将成功. (2认同)