2006年05月09日
川俣晶の縁側ソフトウェア技術雑記total 10823 count

C# 2.0で、InternalsVisibleTo属性を用いてアセンブリ内でのみ使用される機能を単体テストする方法

Written By: 川俣 晶連絡先

 中さんのブログを見ていて、C# 2.0に決定的な見落としがあることに気付きました。

 これは、即座に存在に気付いてリアクションすべきだった機能です。他のどのような機能強化よりも、私にとっては重要です。

 いろいろ時間を取られて目が行き届いていないのがバレバレ (汗。

問題・単体テストとinternal §

 プログラムの複雑度を低減するという観点から言えば、あらゆる箇所から参照できる"public"の利用は、全く好ましいことではありません。

 これは、インテリセンスで表示される候補が不必要に増えるという意味でも生産性を低下させる要因となります。

 C#において、これを解決するための手段は十分にあるとは言えません。

 強いて言えば、"public"ではなく、"internal"が解決策となります。これを使うことで、特定アセンブリ内からのみアクセスを許可することを明示できます。

 ところが、"internal"は、単体テスト(テスト駆動開発)との併用で決定的な問題を引きおこします。テストメソッドは、通常、別のアセンブリ上に記述しますが、"internal"スコープ上のクラスやメソッドを呼び出せないのです。

解決・InternalsVisibleToAttribute §

 InternalsVisibleToAttributeを使うと、指定したアセンブリに対してのみ、"internal"スコープのクラスやメソッドを公開することができます。

 これを使うことで、テスト・アセンブリにのみアクセスを許す"internal"スコープのクラスやメソッドを記述できます。

サンプルソース §

 NUnitを用いて、実際にInternalスコープのメソッドをテストする例です。

 Visual Studio 2005を用いて、C#の2つのクラスライブラリのプロジェクトを含むソリューションを作成します。

テスト対象のクラス §

using System;

using System.Collections.Generic;

using System.Text;

namespace NUnitAndFrientAssembly001

{

    internal class ClassTarget

    {

        internal int Add(int x, int y)

        {

            return x + y;

        }

    }

}

テストを行うクラス §

(注: テスト対象のクラスを含むプロジェクトと、nunit.framework.dllへの参照を追加する必用があります)

using System;

using System.Collections.Generic;

using System.Text;

using NUnit.Framework;

using NUnitAndFrientAssembly001;

namespace TestNUnitAndFrientAsembly001

{

    [TestFixture]

    public class TestClassTaregt

    {

        [Test]

        public void TryTestAdd()

        {

            ClassTarget t = new ClassTarget();

            Assert.AreEqual(3, t.Add(1, 2));

        }

    }

}

テスト対象のクラスを含むプロジェクトのAssemblyInfo.csに追加した行 §

[assembly: InternalsVisibleTo("TestNUnitAndFrientAsembly001")]

※ 上記の行を入れないと、ビルドが失敗します。つまり、それがInternalsVisibleToAttributeの効能です。

感想 §

 いいぞ。この機能は好きです。

 100点満点にはほど遠いですが、アセンブリをカプセル化の単位として扱いつつ、アセンブリ内の隠されたクラスを単体テストの対象にできます。

 Genericsの価値を1とすれば、この機能の価値は(私にとって)100ぐらいにあたります。

 既存のC#ソース資産に対して、今すぐ使える改善策としては、十分すぎるほど優秀です。

 単にこれを使うために、Visual Studio.NET 2003ベースのソースを、早急に2005ベースに移行しても良いぐらい好き。

 ちなみに、C#で可能ということは、他の言語はどうだろうと思って軽く見てみると、VBでは無理っぽい? C++/CLIでは、#using "……" as_friendのような構文を併用しつつ使える?

 残念ながら時間がないので、この場はここまで!

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2006年
06月
18日
.NET Framework 1.1→2.0非互換性: XmlDocument.LoadメソッドのURL解釈が異なる
3days 0 count
total 3300 count
【技術雑記】の前のコンテンツ
2006年
04月
15日
UTFの種類一覧
3days 0 count
total 6846 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20060509190737
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.33 (Alpha-Test) Copyright (c) 2004-2018 Pie Dey.Co.,Ltd.