1.21 jigowatts

Great Scott!

【.NET Core】MoqのQuickstartをやってみる(Verification)

概要

MoqのQuickstartをやってみる。今回はVerifyメソッドです。

github.com

環境
  • macOS Sierra バージョン 10.12.6
  • .NET Core 2.0
  • Moq 4.7.137

テストコード

こんな感じかなぁ。

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using MoqQuickstart;

namespace MoqQuickstart.Tests
{
    [TestClass]
    public class Verification
    {
        [TestMethod]
        public void verify()
        {
            var mock = new Mock<IFoo>();
            mock.Object.DoSomething("ping");
            mock.Verify(foo => foo.DoSomething("ping"));
        }

        [TestMethod]
        public void verify_with_custom_error_message_for_failure()
        {
            var mock = new Mock<IFoo>();
            mock.Verify(foo => foo.DoSomething("ping"), "When doing operation X, the service should be pinged always");
        }

        [TestMethod]
        public void method_should_never_be_called()
        {
            var mock = new Mock<IFoo>();
            mock.Verify(foo => foo.DoSomething("ping"), Times.Never());
        }

        [TestMethod]
        public void called_at_least_once()
        {
            var mock = new Mock<IFoo>();
            mock.Object.DoSomething("ping");
            mock.Verify(foo => foo.DoSomething("ping"), Times.AtLeastOnce());
        }

        [TestMethod]
        public void verify_getter_invocation_regardless_of_value()
        {
            var mock = new Mock<IFoo>();
            var name = mock.Object.Name;
            mock.VerifyGet(foo => foo.Name);
        }

        [TestMethod]
        public void verify_setter_invocation_regardless_of_value()
        {
            var mock = new Mock<IFoo>();
            mock.Object.Name = "foo";
            mock.VerifySet(foo => foo.Name);
        }

        [TestMethod]
        public void verify_setter_called_with_specific_value()
        {
            var mock = new Mock<IFoo>();
            mock.Object.Name = "foo";
            mock.VerifySet(foo => foo.Name ="foo");
        }

        [DataTestMethod]
        [DataRow(1)]
        [DataRow(3)]
        [DataRow(5)]
        public void verify_setter_with_an_argument_matcher(int value)
        {
            var mock = new Mock<IFoo>();
            mock.Object.Value = value;
            mock.VerifySet(foo => foo.Value = It.IsInRange(1, 5, Range.Inclusive));
        }
    }
}

テストを実行してみましょう。
verify_with_custom_error_message_for_failureでちゃんとエラーメッセージも表示されていますね!

$ dotnet test --filter "FullyQualifiedName~MoqQuickstart.Tests.Verification"
Build started, please wait...
Build completed.

Test run for /Users/soil/src/github/unit-testing-using-dotnet-test/PrimeService.Tests/bin/Debug/netcoreapp2.0/PrimeService.Tests.dll(.NETCoreApp,Version=v2.0)
Microsoft (R) Test Execution Command Line Tool Version 15.3.0-preview-20170628-02
Copyright (c) Microsoft Corporation.  All rights reserved.

テスト実行を開始しています。お待ちください...
失敗   MoqQuickstart.Tests.Verification.verify_with_custom_error_message_for_failure
エラー メッセージ:
 Test method MoqQuickstart.Tests.Verification.verify_with_custom_error_message_for_failure threw exception: 
Moq.MockException: When doing operation X, the service should be pinged always
Expected invocation on the mock at least once, but was never performed: foo => foo.DoSomething("ping")
No setups configured.
No invocations performed.
スタック トレース:
    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.Verify[T,TResult](Mock`1 mock, Expression`1 expression, Times times, String failMessage)
   at Moq.Mock`1.Verify[TResult](Expression`1 expression, String failMessage)
   at MoqQuickstart.Tests.Verification.verify_with_custom_error_message_for_failure() in /Users/soil/src/github/unit-testing-using-dotnet-test/PrimeService.Tests/Verification.cs:line 23


テストの合計数: 10。成功: 9。失敗:1。スキップ: 0
テストの実行に失敗しました。
テスト実行時間: 2.3554 秒

はい、次!