« [.NET] フィードバック - MSTest: ClassCleanup() のタイミングを早くしてほしい ( その2 ) | トップページ | XP SP3 一般公開 »

2008年5月 2日 (金)

[.NET] 抽象クラスの private メソッドを単体テストする @VS2008

※ このコンテンツは、 TDD.NET に移動します。

こんなテストターゲットがあったとします。

namespace 抽象クラス {
    internal abstract class AbstractClass1 {
        protected int _num;
        internal AbstractClass1() {
            this._num = 1;
        }
        protected abstract bool foo(int n);
        private bool bar(int n) {
            return (this._num == n);
        }
    }
}

さて、 この private なメソッド bar() を、 Visual Studio 2008 のユニットテスト機能で、 直接テスト出来るでしょうか?

※ 通常は、 private メソッドを呼び出している protected 以上のメソッドが必ず存在しますから、 そこをテストすることで間接的に private メソッドをテストできます。 その手法では、 対象メソッドが複雑すぎてやってられない、 というとき、 private メソッドを直接テストしたくなるわけです。

まず、 いくらなんでも抽象クラスだけではインスタンス化できませんから、 どうしても実装クラスは必要です。

namespace 抽象クラス {
#if UNIT_TEST
    internal class ConcreteClass1 : AbstractClass1 {
        protected override bool foo(int n) {
            return (base._num != n);
        }
    }
#endif
}

この ConcreteClass1 に対して、 単体テストウィザードでテストコードを自動生成させれば、 ConcreteClass1 の方に実装されている protected メソッド foo() はテストできます。 ( InternalsVisibleTo 属性を有効にさせるのを、 忘れずに。 )

でも、 それで自動生成された ConcreteClass1_Accessor クラスを使って、 親クラスの private メソッド bar() をテストしようとしても、 出来ません。

そこで、 こんな風にして AbstractClass1 のアクセッサを作ってやります。

    [TestMethod()]
    [DeploymentItem("抽象クラス.dll")]
    public void barTest()
    {
        // 実装クラスのインスタンスから、
        // 抽象クラス (親) の Accessor を生成する。
        PrivateObject po = new PrivateObject(
            new ConcreteClass1(),
            new PrivateType(typeof(AbstractClass1))
            );
        AbstractClass1_Accessor target
            = new AbstractClass1_Accessor(po);

        // 親クラスの実装 private bar()
        Assert.IsFalse(target.bar(0));
        Assert.IsTrue(target.bar(1));

        // 子クラスの実装 protected foo() も見える
        Assert.IsTrue(target.foo(0));
        Assert.IsFalse(target.foo(1));
    }

※ このコンテンツは、 TDD.NET に移動します。

|

« [.NET] フィードバック - MSTest: ClassCleanup() のタイミングを早くしてほしい ( その2 ) | トップページ | XP SP3 一般公開 »

プログラミング」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: [.NET] 抽象クラスの private メソッドを単体テストする @VS2008:

« [.NET] フィードバック - MSTest: ClassCleanup() のタイミングを早くしてほしい ( その2 ) | トップページ | XP SP3 一般公開 »