今回はC#&NUnitでTDDをしつつ、インデクサを使ってコードを書いてみることにしました。
インデクサとは、クラスに配列のように[]でアクセスすることができるようにするプロパティです。うーん、説明下手でスミマセン。インデクサの詳しい説明は他のサイトに任せるとして、今日はC#とNUnitを使ってみます。
ちなみに今回、テーマが決まらずに++C++;// 未確認飛行 Cのコードを参考にさせていただいています。ちょっと変えて、上限のみ設定できるようにしています…そのせいでほぼ、ただの配列になってます。そのため、配列の平均と合計を計算するようにしてみました。はっきり言って蛇足です。
class UpperBoundArray { int[] array; int upper; public UpperBoundArray(int upper) { this.upper = upper; array = new int[upper + 1]; } public int this[int i] { set { this.array[i] = value; } get { return this.array[i]; } } public double average() { return sum() / upper; } public int sum() { int s = 0; foreach (int i in array) s += i; return s; } }
UpperBoundArray.cs
using System; using NUnit.Framework; [TestFixture] class BoundArrayTest { private UpperBoundArray bA; [TestFixtureSetUp] public void testFixtureSetUp() { bA = new UpperBoundArray(4); for (int i = 0; i <= 4; i++) bA[i] = i; } [Test] public void testIndexer() { Assert.That(bA[0], Is.EqualTo(0)); Assert.That(bA[1], Is.EqualTo(1)); Assert.That(bA[2], Is.EqualTo(2)); Assert.That(bA[3], Is.EqualTo(3)); Assert.That(bA[4], Is.EqualTo(4)); } [Test] [ExpectedException(typeof(IndexOutOfRangeException))] public void testIndexerOutOfRangeException() { bA[5] = 5; } [Test] public void testAverage() { Assert.That(bA.average(), Is.EqualTo(2)); } [Test] public void testSum() { Assert.That(bA.sum(), Is.EqualTo(10)); } }
UpperBoundArrayTest.cs
初めて例外のテストをしてみました。今回は配列が境界の外を参照したときに発生する例外(IndexOutOfRangeException)をテストしています。他の言語でも例外のテストを触ってみたいですね。
追記:友人に指摘されたので、テストコードをちょっとリファクタリングしてみます。テストコードでインデクサのアクセスをテストしている部分ですが、属性[TestCase]を使うことでコードの重複を抑えられます。
/* 上のtestIndexer()と同じテストを実行 */ [TestCase(0, 0)] [TestCase(1, 1)] [TestCase(2, 2)] [TestCase(3, 3)] [TestCase(4, 4)] public void testIndexer(int input, int expected) { Assert.That(bA[input], Is.EqualTo(expected)); }
こうすることで、テストコードの重複を抑えることができます。(今回で言うとAssert.That()の繰り返し)。また、視覚的に入力値と期待値が見えるという効果も期待できます。
まだまだ勉強中なので、こうした「最適なコード」へと自分の書くコードを昇華することができるように努力していきたいと思います。