diff --git a/Assets/APIExamples/Tests/Runtime/NUnit/CustomComparerExample.cs b/Assets/APIExamples/Tests/Runtime/NUnit/CustomComparerExample.cs index e2a718f..9086cba 100644 --- a/Assets/APIExamples/Tests/Runtime/NUnit/CustomComparerExample.cs +++ b/Assets/APIExamples/Tests/Runtime/NUnit/CustomComparerExample.cs @@ -1,67 +1,62 @@ -// Copyright (c) 2021 Koji Hasegawa. +// Copyright (c) 2021-2023 Koji Hasegawa. // This software is released under the MIT License. using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using NUnit.Framework; -using NUnit.Framework.Constraints; +using UnityEngine; // ReSharper disable AccessToStaticMemberViaDerivedType namespace APIExamples.NUnit { /// - /// + Using修飾子と、カスタムの使用例 + /// Using修飾子と、カスタムの使用例 /// public class CustomComparerExample { [Test] - public void EqualConstraint_Using修飾子で比較() + public void EqualConstraint_Using修飾子でカスタムComparerを指定して比較() { - var actual = new CompositeKeySUT("Foo", "Bar", 1); + var actual = new GameObject("test object"); + var expected = new GameObject("test object"); - Assert.That(actual, Is.EqualTo(new CompositeKeySUT("Foo", "Bar", 10)).Using(new CompositeKeySUTComparer())); + Assert.That(actual, Is.EqualTo(expected).Using(new GameObjectNameComparer())); // 失敗時メッセージ例: - // Expected: - // But was: + // Expected: + // But was: } [Test] - public void EqualConstraint_コレクションの要素をUsing修飾子で比較() + public void CollectionContainsConstraint_コレクションの要素をUsing修飾子でカスタムComparerを指定して比較() { - var actual = new[] { new CompositeKeySUT("Foo", "Bar", 1), new CompositeKeySUT("Bar", "Baz", 2) }; + var actual = new[] { new GameObject("test1"), new GameObject("test2"), new GameObject("test3"), }; + var expected = new GameObject("test3"); - Assert.That(actual, - Is.EqualTo(new[] { new CompositeKeySUT("Foo", "Bar", 10), new CompositeKeySUT("Bar", "Baz", 20) }) - .Using(new CompositeKeySUTComparer())); + Assert.That(actual, Does.Contain(expected).Using(new GameObjectNameComparer())); // 失敗時メッセージ例: - // Expected and actual are both - // Values differ at index [1] - // Expected: - // But was: + // Expected: collection containing + // But was: < , , > } } /// - /// カスタムの実装例 + /// カスタムの実装例. + /// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。 /// - public class CompositeKeySUTComparer : IComparer + public class GameObjectNameComparer : IComparer { /// - /// Key1 + Key2 で比較 + /// GameObject 同士を、参照でなく name プロパティで比較するカスタムComparer /// /// /// /// - public int Compare(CompositeKeySUT x, CompositeKeySUT y) + [SuppressMessage("ReSharper", "PossibleNullReferenceException")] + public int Compare(GameObject x, GameObject y) { - var key1Comparison = string.Compare(x.Key1, y.Key1, StringComparison.Ordinal); - if (key1Comparison != 0) - { - return key1Comparison; - } - - return string.Compare(x.Key2, y.Key2, StringComparison.Ordinal); + return string.Compare(x.name, y.name, StringComparison.Ordinal); } } } diff --git a/Assets/APIExamples/Tests/Runtime/NUnit/CustomConstraintExample.cs b/Assets/APIExamples/Tests/Runtime/NUnit/CustomConstraintExample.cs index 81f8938..ac17bde 100644 --- a/Assets/APIExamples/Tests/Runtime/NUnit/CustomConstraintExample.cs +++ b/Assets/APIExamples/Tests/Runtime/NUnit/CustomConstraintExample.cs @@ -1,98 +1,138 @@ -// Copyright (c) 2021 Koji Hasegawa. +// Copyright (c) 2021-2023 Koji Hasegawa. // This software is released under the MIT License. using NUnit.Framework; using NUnit.Framework.Constraints; +using UnityEngine; // ReSharper disable AccessToStaticMemberViaDerivedType namespace APIExamples.NUnit { /// - /// カスタムの使用例 + /// カスタム制約の使用例 /// [TestFixture] public class CustomConstraintExample { + private static GameObject CreateDestroyedObject() + { + var gameObject = new GameObject("Foo"); + GameObject.DestroyImmediate(gameObject); + return gameObject; + } + + [Test] + public void CustomConstraint_Constraintの実装だけで可能な書きかた() + { + var actual = CreateDestroyedObject(); + + Assert.That(actual, new DestroyedConstraint()); + // 失敗時メッセージ例: + // Expected: destroyed GameObject + // But was: + } + [Test] - public void CustomEqConstraint_Constraintの実装だけで可能な書きかた() + public void CustomConstraint_Extensionsの実装も行なうと可能な書きかた() { - var actual = "Foo bar"; + var actual = CreateDestroyedObject(); - Assert.That(actual, new CustomEqConstraint("Foo bar")); + Assert.That(actual, Is.Not.Null.And.Destroyed()); // 失敗時メッセージ例: - // Expected: "Foo bar"(カスタム制約) - // But was: "Foo bar baz" + // Expected: not null and destroyed GameObject + // But was: } [Test] - public void CustomEqConstraint_Extensionsの実装も行なうと可能な書きかた() + public void CustomConstraint_Isの実装も行なうと可能な書きかた() { - var actual = "Foo bar"; + var actual = CreateDestroyedObject(); - Assert.That(actual, Is.Not.Null.And.CustomEq("Foo bar")); + Assert.That(actual, Is.Destroyed); // 失敗時メッセージ例: - // Expected: not null and "Foo bar"(カスタム制約) - // But was: "Foo bar baz" + // Expected: destroyed GameObject + // But was: } [Test] - public void CustomEqConstraint_Isの実装も行なうと可能な書きかた() + public void CustomConstraint_Isの実装も行なうと可能な書きかた_Not() { - var actual = "Foo bar"; + var actual = new GameObject("Bar"); - Assert.That(actual, Is.CustomEq("Foo bar")); + Assert.That(actual, Is.Not.Destroyed()); // 失敗時メッセージ例: - // Expected: "Foo bar"(カスタム制約) - // But was: "Foo bar baz" + // Expected: not destroyed GameObject + // But was: } } /// - /// カスタムの実装例 + /// カスタム制約の実装例. + /// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。 /// - /// - /// 内容は文字列が一致するか判定しているだけ - /// - public class CustomEqConstraint : Constraint + public class DestroyedConstraint : Constraint { - public CustomEqConstraint(params object[] args) : base(args) { } + public DestroyedConstraint(params object[] args) : base(args) + { + base.Description = "destroyed GameObject"; // 失敗時メッセージに出力される + } + /// + /// Assert.Thatから渡されるactualオブジェクトを検証する、カスタム制約の本体 + /// + /// 検証対象オブジェクト + /// 制約の成否 public override ConstraintResult ApplyTo(object actual) { - return new ConstraintResult(this, actual, actual.ToString() == Arguments[0].ToString()); - } + if (actual is GameObject actualGameObject) + { + return new ConstraintResult(this, actual, (bool)actualGameObject == false); + // GameObjectであれば、破棄されているかを判定して結果として返す + } - public override string Description { get { return $"\"{Arguments[0]}\"(カスタム制約)"; } } + return new ConstraintResult(this, actual, false); + // GameObjectでなければ常にfalse + } } /// - /// カスタム向けの拡張メソッド + /// カスタム制約のための拡張クラス. + /// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。 /// - public static class CustomConstraintExtensions + public static class ConstraintExtensions { - public static CustomEqConstraint CustomEq(this ConstraintExpression expression, object expected) + /// + /// カスタム制約のための拡張メソッド. + /// 式にDestroyedが指定されたとき、Destroyed制約のインスタンスをexpressionに追加して返します。 + /// + /// + /// constraint to destroyed GameObject + public static DestroyedConstraint Destroyed(this ConstraintExpression expression) + // Note: 比較対象がある制約の場合、第2引数で object expected を受け取ります { - var constraint = new CustomEqConstraint(expected); + var constraint = new DestroyedConstraint(); expression.Append(constraint); return constraint; } } /// - /// カスタム向けのクラス + /// カスタム制約のためのクラス. + /// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。 /// /// - /// Unity Test Framework には NUnit.Framework.Is を継承した UnityEngine.TestTools.Constraints.Is がすでにあるため、 - /// これを継承して作ります。 - /// UnityEngine.TestTools.Constraints.Is が必要なければ、直接 global::NUnit.Framework.Is を継承しても構いません。 + /// Unity Test Framework には NUnit.Framework.Is を継承した UnityEngine.TestTools.Constraints.Is がすでにあるため、これを継承して作ります。 + /// Test Helperパッケージも使用するのであれば、TestHelper.Constraints.Is を継承します。 + /// UnityEngine.TestTools.Constraints.Is も TestHelper.Constraints.Is も必要なければ、直接 global::NUnit.Framework.Is を継承しても構いません。 /// // ReSharper disable once ClassNeverInstantiated.Global public class Is : UnityEngine.TestTools.Constraints.Is { - public static CustomEqConstraint CustomEq(object expected) - { - return new CustomEqConstraint(expected); - } + /// + /// Create constraint to destroyed GameObject. + /// + public static DestroyedConstraint Destroyed => new DestroyedConstraint(); + // Note: 比較対象がある制約の場合、引数で object expected を受け取ります } } diff --git a/README.md b/README.md index 9eb3940..80ef479 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,12 @@ Assets     └── 第5章 非同期処理のテスト, 第9章 Unity Test Framework Tips ``` +> **Note** +> 『Unity Test Framework完全攻略ガイド』6.4 カスタムアサーションの例を、v2.1.0(2023-11-11版)で書き換えました。 +> 変更差分はコミット <[dc1b643](https://github.com/nowsprinting/UnityTestExamples/commit/dc1b643cd7e1275388881933b5edfcabde0413ba)> を参照してください。 + + + ### BasicExample 第2章 Unity Test Frameworkの基本