1. ホーム
  2. c#

[解決済み] 複素数パラメータを[理論]に渡す

2022-07-04 11:47:10

質問

Xunitにはいい機能があります で一つのテストを作ることができます。 Theory 属性で一つのテストを作り、データを InlineData 属性にデータを入れると、xUnit はたくさんのテストを生成し、それらをすべてテストします。

このようなものが欲しいのですが、私のメソッドのパラメータは「単純なデータ」ではなく、(例えば string , int , double のように)、自分のクラスのリストです。

public static void WriteReportsToMemoryStream(
    IEnumerable<MyCustomClass> listReport,
    MemoryStream ms,
    StreamWriter writer) { ... }

どのように解決するのですか?

多くの xxxxData 属性があります。例えば MemberData 属性を見てみましょう。

を返すプロパティを実装することができます。 IEnumerable<object[]> . それぞれ object[] を呼び出す際のパラメータとして使用されます。 [Theory] メソッドを呼び出す際のパラメータとなります。

を参照してください。 の例は、ここから

ざっと見た感じでは、こんな感じの例です。

MemberDataの例: 手元にあるものだけ

public class StringTests2
{
    [Theory, MemberData(nameof(SplitCountData))]
    public void SplitCount(string input, int expectedCount)
    {
        var actualCount = input.Split(' ').Count();
        Assert.Equal(expectedCount, actualCount);
    }
 
    public static IEnumerable<object[]> SplitCountData => 
        new List<object[]>
        {
            new object[] { "xUnit", 1 },
            new object[] { "is fun", 2 },
            new object[] { "to test with", 3 }
        };
}

XUnit < 2.0です。もう一つの選択肢は ClassData これは同じように動作しますが、異なるクラス/名前空間内のテスト間で「ジェネレータ」を簡単に共有することができます。また、「データジェネレータ」と実際のテストメソッドを分離することもできます。

ClassData の例

public class StringTests3
{
    [Theory, ClassData(typeof(IndexOfData))]
    public void IndexOf(string input, char letter, int expected)
    {
        var actual = input.IndexOf(letter);
        Assert.Equal(expected, actual);
    }
}
 
public class IndexOfData : IEnumerable<object[]>
{
    private readonly List<object[]> _data = new List<object[]>
    {
        new object[] { "hello world", 'w', 6 },
        new object[] { "goodnight moon", 'w', -1 }
    };
 
    public IEnumerator<object[]> GetEnumerator()
    { return _data.GetEnumerator(); }
 
    IEnumerator IEnumerable.GetEnumerator()
    { return GetEnumerator(); }
}

XUnit >=2.0です。の代わりに ClassData の代わりに、他のクラスの静的メンバを使用できる [MemberData] の「オーバーロード」が追加されました。XUnit < 2.xはかなり古くなったので、以下の例はこれを使用するように更新されました。 もう一つの方法として ClassData これは同じように動作しますが、異なるクラスや名前空間のテスト間で簡単に「ジェネレータ」を共有することができます。また、実際のテストメソッドから「データジェネレータ」を分離することもできます。

MemberDataの例: 別の型に目を向ける

public class StringTests3
{
    [Theory, MemberData(nameof(IndexOfData.SplitCountData), MemberType = typeof(IndexOfData))]
    public void IndexOf(string input, char letter, int expected)
    {
        var actual = input.IndexOf(letter);
        Assert.Equal(expected, actual);
    }
}
 
public class IndexOfData : IEnumerable<object[]>
{
    public static IEnumerable<object[]> SplitCountData => 
        new List<object[]>
        {
            new object[] { "hello world", 'w', 6 },
            new object[] { "goodnight moon", 'w', -1 }
        };
}

免責事項 :)

前回、C# 5.0 と xunit 2.4.1 で dotnetfiddle.net を使って @20210903 をチェックしましたが......失敗しました。そのfiddleにテストランナーを混ぜることができなかったのです。しかし,少なくともコンパイルはうまくいった.なお,これは何年も前に書いたもので,少し状況が変わっている.私の直感とコメントに従って修正しました。そのため、明らかな誤字脱字や、実行時に即座に現れるような明らかなバグ、牛乳やナッツの痕跡があるかもしれません。