xUnitのテストメソッドのカスタム属性で名前付き引数を利用したい

xUnitのテストメソッドのカスタム属性で名前付き引数を利用するコードを紹介します。

概要

こちらの記事では、テストメソッドにカスタム属性を実装して、 ファイルからテストデータと結果データを読み込んでテストするコードを紹介しました。
紹介したコードで問題なく動作しますが、パラメーターに名前を付けて、わかりやすくしたい場合があります。
この記事では、テストメソッドのカスタム属性で名前付き引数に対応するコードを紹介します。

元の記述
    [Theory]
    [FileTestData("test1.txt", "result1.txt")]
    [FileTestData("test2.txt", "result2.txt")]
    [FileTestData("test3.txt", "result3.txt")]
    public void Test1(string fileName, string test, string result)
    {
      MyClass m = new MyClass();

      Assert.Equal(m.proc(test), result);
    }
  }

名前付き引数を利用した記述
    [Theory]
    [FileTestData(CaseFileName = "test1.txt", ResultFileName = "result1.txt")]
    [FileTestData(CaseFileName = "test2.txt", ResultFileName = "result2.txt")]
    [FileTestData(CaseFileName = "test3.txt", ResultFileName = "result3.txt")]
    public void Test1(string fileName, string test, string result)
    {
      MyClass m = new MyClass();

      Assert.Equal(m.proc(test), result);
    }

プログラム例

コード

テストプロジェクトを作成し、以下のコードを記述します。
MyClassは別プロジェクトのクラスのため、テスト元クラスへの参照を追加する必要があります。

using System.Reflection;
using Xunit.Sdk;
using xUnitTestDataAttribute;

namespace xUnitTestDataNamedAttributeTest
{
  public class UnitTest1
  {
    [Theory]
    [FileTestData(CaseFileName = "test1.txt", ResultFileName = "result1.txt")]
    [FileTestData(CaseFileName = "test2.txt", ResultFileName = "result2.txt")]
    [FileTestData(CaseFileName = "test3.txt", ResultFileName = "result3.txt")]
    public void Test1(string fileName, string test, string result)
    {
      MyClass m = new MyClass();

      Assert.Equal(m.proc(test), result);
    }
  }

  public class FileTestDataAttribute : DataAttribute
  {
    public string CaseFileName { get; set; }
    public string ResultFileName { get; set; }
 
    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
      string TestCase = System.IO.File.ReadAllText(CaseFileName);
      string ResultCase = System.IO.File.ReadAllText(ResultFileName);

      List<object[]> result = new List<object[]>();
      result.Add(new object[] { CaseFileName, TestCase, ResultCase });

      return result;
    }
  }
}

解説

名前付き引数に対応する場合は、FileTestDataAttribute クラスに、引数の名前のプロパティを実装します。

別の実装方法

引数名 : "引数値" の記述方法で指定する方式でよい場合は、以下の記述もできます。

using System.Reflection;
using Xunit.Sdk;
using xUnitTestDataAttribute;

namespace xUnitTestDataNamedAttributeTest
{
  public class UnitTest1
  {
    [Theory]
    [FileTestData(CaseFileName : "test1.txt", ResultFileName : "result1.txt")]
    [FileTestData(CaseFileName : "test2.txt", ResultFileName : "result2.txt")]
    [FileTestData(CaseFileName : "test3.txt", ResultFileName : "result3.txt")]
    public void Test1(string fileName, string test, string result)
    {
      MyClass m = new MyClass();

      Assert.Equal(m.proc(test), result);
    }
  }

  public class FileTestDataAttribute : DataAttribute
  {
    private string _caseFileName;
    private string _resultFileName;
    
    public FileTestDataAttribute(string CaseFileName, string ResultFileName)
    {
      _caseFileName = CaseFileName;
      _resultFileName = ResultFileName;
    }
    
    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
      string TestCase = System.IO.File.ReadAllText(_caseFileName);
      string ResultCase = System.IO.File.ReadAllText(_resultFileName);

      List<object[]> result = new List<object[]>();
      result.Add(new object[] { _caseFileName, TestCase, ResultCase });

      return result;
    }

  }
}
AuthorPortraitAlt
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
作成日: 2025-01-01
Copyright © 1995–2025 iPentec all rights reserverd.