AssertとCollectionAssert、StringAssertの使用例

AssertとCollectionAssert、StringAssertを試してみた。

# Assert

```c#:AssertTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Threading.Tasks;

namespace UnitTestProject1
{
    [TestClass()]
    public class AssertTests
    {
        [TestMethod()]
        public void AssertTest()
        {
            Assert.AreEqual(1, 1);
            Assert.AreEqual(1.0, 1.05, 0.1);
            Assert.AreEqual("A", "a", true);
            Assert.AreNotEqual(1, 2);
            Assert.AreNotEqual(1.0, 1.15, 0.1);
            Assert.AreNotEqual("A", "b", true);
            Assert.AreNotSame(new StringBuilder("A").ToString(), new StringBuilder("A").ToString());
            string a1 = "A";
            string a2 = a1;
            Assert.AreSame(a1, a2);
            Assert.IsFalse(false);
            Assert.IsInstanceOfType("A", typeof(string));
            Assert.IsNotInstanceOfType("A", typeof(int));
            Assert.IsNotNull("A");
            Assert.IsNull(null);
            Assert.IsTrue(true);
            var e = Assert.ThrowsException<ArgumentNullException>(() => throw new ArgumentNullException("AAA"));
            Assert.AreEqual("AAA", e.ParamName);
            var t = Assert.ThrowsExceptionAsync<ArgumentNullException>(() => Task.Factory.StartNew(() => throw new ArgumentNullException("AAA")));
            Assert.AreEqual("AAA", t.Result.ParamName);
        }
    }
}
```

## AssertExtensions

拡張メソッドでAssertにメソッドを追加する。

```c#:AssertExtensions.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;

namespace UnitTestProject1
{
    public static class AssertExtensions
    {
        public static void IsOfType<T>(this Assert assert, object obj)
        {
            if (typeof(T).Equals(obj.GetType())) return;
            throw new AssertFailedException("AssertExtensions.IsOfType");
        }

        public static void AreEqual(this Assert assert,
            System.Windows.Point expected, System.Windows.Point actual,
            double delta)
        {
            Assert.AreEqual(expected.X, actual.X, delta);
            Assert.AreEqual(expected.Y, actual.Y, delta);
        }

        public static async Task<Exception> ThrowsExceptionAsync<T1, T2>(
            this Assert assert, Func<Task> action)
            where T1 : Exception
            where T2 : Exception
        {
            if (action == null) throw new ArgumentNullException(nameof(action));
            try
            {
                await action();
            }
            catch (Exception ex)
            {
                if (typeof(T1).Equals(ex.GetType())) return ex;
                if (typeof(T2).Equals(ex.GetType())) return ex;
            }
            throw new AssertFailedException("AssertExtensions.ThrowsExceptionAsync");
        }
    }
}
```

```c#:AssertExtensionsTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;

namespace UnitTestProject1
{
    [TestClass()]
    public class AssertExtensionsTests
    {
        [TestMethod()]
        public void IsOfTypeTest()
        {
            object actual = string.Empty;
            Assert.That.IsOfType<string>(actual);
        }

        [TestMethod()]
        public void AreEqualTest()
        {
            var expected = new System.Windows.Point(1.0, 1.0);
            var actual = new System.Windows.Point(1.05, 1.05);
            Assert.That.AreEqual(expected, actual, 0.1);
        }

        private static Task ThrowArgumentExceptionAsync()
            => throw new ArgumentException();

        private static Task ThrowArgumentNullExceptionAsync()
            => throw new ArgumentNullException();

        [TestMethod()]
        public async Task ThrowsExceptionAsyncTestAsync()
        {
            await Assert.That.ThrowsExceptionAsync
                <ArgumentException, ArgumentNullException>
                (async () => await ThrowArgumentExceptionAsync());

            await Assert.That.ThrowsExceptionAsync
                <ArgumentException, ArgumentNullException>
                (async () => await ThrowArgumentNullExceptionAsync());
        }
    }
}
```

# CollectionAssert

```c#:CollectionAssertTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections;

namespace UnitTestProject1
{
    class NoCaseStringComparer : IComparer
    {
        public static NoCaseStringComparer Instance { get; } = new NoCaseStringComparer();

        public int Compare(object x, object y)
        {
            if (x == null) return y == null ? 0 : 1;
            if (y == null) return -1;
            return string.Compare((string)x, (string)y, true);
        }
    }

    [TestClass]
    public class CollectionAssertTests
    {
        [TestMethod()]
        public void CollectionAssertTest()
        {
            CollectionAssert.AllItemsAreInstancesOfType(new string[] { "A", "B", }, typeof(string));
            CollectionAssert.AllItemsAreNotNull(new string[] { "A", "B", });
            CollectionAssert.AllItemsAreUnique(new string[] { "A", "B", });
            CollectionAssert.AreEqual(new string[] { "A", "B", }, new string[] { "A", "B", });
            CollectionAssert.AreEqual(new string[] { "A", "B", }, new string[] { "a", "b", }, NoCaseStringComparer.Instance);
            // AreEquivalentは順不同
            CollectionAssert.AreEquivalent(new string[] { "A", "B", }, new string[] { "B", "A", });
            CollectionAssert.AreNotEqual(new string[] { "A", "B", }, new string[] { "A", });
            CollectionAssert.AreNotEqual(new string[] { "A", "B", }, new string[] { "A", "C", });
            CollectionAssert.AreNotEquivalent(new string[] { "A", "B", }, new string[] { "B", });
            CollectionAssert.AreNotEquivalent(new string[] { "A", "B", }, new string[] { "C", "B", });
            CollectionAssert.Contains(new string[] { "A", "B", }, "A");
            CollectionAssert.DoesNotContain(new string[] { "A", "B", }, "C");
            CollectionAssert.IsNotSubsetOf(new string[] { "D", "B", }, new string[] { "A", "B", "C", });
            // IsSubsetOfは順不同
            CollectionAssert.IsSubsetOf(new string[] { "C", "B", }, new string[] { "A", "B", "C", });
        }
    }
}
```

# StringAssert

```c#:StringAssertTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;

namespace UnitTestProject1
{
    [TestClass()]
    public class StringAssertTests
    {
        [TestMethod()]
        public void ContainsTest()
        {
            var postcode = "123-4567";
            StringAssert.Contains(postcode, "123");
            StringAssert.Contains(postcode, "3-4");
            StringAssert.Contains(postcode, "4567");
            StringAssert.Contains(postcode, "123-4567");
        }

        [TestMethod()]
        public void DoesNotMatchTest()
        {
            var postcode = "123-4567";
            StringAssert.DoesNotMatch(postcode, new Regex("XXXXX"));
        }

        [TestMethod()]
        public void EndsWithTest()
        {
            var postcode = "123-4567";
            StringAssert.EndsWith(postcode, "4567");
            StringAssert.EndsWith(postcode, "123-4567");
        }

        [TestMethod()]
        public void MatchesTest()
        {
            var postcode = "123-4567";
            StringAssert.Matches(postcode, new Regex(@"^\d{3}-\d{4}$"));
        }

        [TestMethod()]
        public void StartsWithTest()
        {
            var postcode = "123-4567";
            StringAssert.StartsWith(postcode, "123");
            StringAssert.StartsWith(postcode, "123-4567");
        }
    }
}
```

## StringAssertExtensions

拡張メソッドでStringAssertにメソッドを追加する。

```c#:StringAssertExtensionsTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;

namespace UnitTestProject1
{
    public static class StringAssertExtensions
    {
        public static void ContainsWords(this StringAssert assert,
            string value, IEnumerable<string> substrings)
        {
            if (substrings.Where(_ => value.Contains(_)).Any()) return;
            throw new AssertFailedException("StringAssertExtensions.ContainsWords");
        }

        public static void ContainsWords(this StringAssert assert,
            string value, params string[] substrings)
        {
            if (substrings.Where(_ => value.Contains(_)).Any()) return;
            throw new AssertFailedException("StringAssertExtensions.ContainsWords");
        }
    }
}
```

```c#:StringAssertExtensionsTests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1
{
    [TestClass()]
    public class StringAssertExtensionsTests
    {
        [TestMethod()]
        public void ContainsWordsTest()
        {
            var postcode = "123-4567";
            var list = new List<string> { "000", "4567" };
            StringAssert.That.ContainsWords(postcode, list);
        }

        [TestMethod()]
        public void ContainsWordsTest2()
        {
            var postcode = "123-4567";
            StringAssert.That.ContainsWords(postcode, "000", "4567");
        }
    }
}
```