1

現在の時刻をプレフィックスとしてコンソールにメッセージを書き込む単純なクラスがあります。IDateTimeProvider抽象化としてインターフェースに依存していますDateTime.Now

public interface IDateTimeProvider
{
    DateTime Now { get; }
    DateTime UtcNow { get; }
}

public class MessageWriter
{
    private readonly IDateTimeProvider _dateTimeProvider;

    public MessageWriter(IDateTimeProvider dateTimeProvider)
    {
        _dateTimeProvider = dateTimeProvider;
    }

    public void Write(string message)
    {
        Console.WriteLine($"{_dateTimeProvider.Now.ToShortTimeString()} : {message}");
    }
}

Writeメソッドの呼び出しをテストするために、IDateTimeProvider.NowxUnit、AutoFixture、および Moq を使用して次のテストを作成しました。

public class MessageWriterTests
{
    [Theory, AutoMoqData]
    public void Write_Always_CallsDateTimeProvider(
        [Frozen] Mock<IDateTimeProvider> dateTimeProviderMock,
        MessageWriter sut,
        string message)
    {
        sut.Write(message);

        dateTimeProviderMock.Verify(m => m.Now, Times.Once());
    }
}

http://blog.ploeh.dk/2010/10/08/AutoDataTheorieswithAutoFixture/AutoMoqDataAttributeで見られるように使用しています

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

上記のテストは、次のメッセージで失敗します。

モックで 1 回の呼び出しが期待されていましたが、3 回でした: m => m.Now

セットアップが構成されていません。

Performed invocations:
IDateTimeProvider.Now
IDateTimeProvider.UtcNow
IDateTimeProvider.Now
IDateTimeProvider.UtcNow
IDateTimeProvider.Now
   at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable`1 setups,  IEnumerable`1 actualCalls, Expression expression, Times times, Int32 callCount)
   at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
   at Moq.Mock.VerifyGet[T,TProperty](Mock`1 mock, Expression`1 expression, Times times, String failMessage)
   at Moq.Mock.Verify[T,TResult](Mock`1 mock, Expression`1 expression, Times times, String failMessage)
   at Moq.Mock`1.Verify[TResult](Expression`1 expression, Times times)
   at MoqBug.Tests.MessageWriterTests.Write_Always_CallsDateTimeProvider(Mock`1 dateTimeProviderMock, MessageWriter sut, String message) in c:\Users\rik van der sanden\documents\visual studio 2015\Projects\MoqBug\MoqBug.Tests\MessageWriterTests.cs:line 21

だから私の質問は: 余分な呼び出し (インターフェイスのプロパティごとに 2 つ) はどこから来るのですか?

問題の使用を控えると、次AutoMoqDataAttributeのようになります。

    [Theory, AutoData]
    public void Write_Always_CallsDateTimeProvider(
        string message)
    {
        IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());
        Mock<IDateTimeProvider> dateTimeProviderMock = fixture.Freeze<Mock<IDateTimeProvider>>();
        MessageWriter sut = fixture.Create<MessageWriter>();

        sut.Write(message);

        dateTimeProviderMock.Verify(m => m.Now, Times.Once());
    }

このバージョンのテストはパスしますが、私はむしろパラメーターを使用してテストを行います。

4

1 に答える 1

1

のバージョン 4.1.1308.2120 を使用していたことが判明しました。これはMoq、現在必要な最低バージョンAutoFixture.AutoMoqであり、Nuget によってインストールされたバージョンです。

Moq最新バージョン (この場合は 4.5.28) に更新すると、問題が修正されました。

于 2016-12-21T17:32:18.553 に答える