1

私は拡張ライブラリを構築しており、http://www.extensionmethod.netにある優れた拡張メソッドを使用して組み込みました。私の単体テスト (NUnit 1.5.2 を使用) で、興味深い問題に遭遇しました。まず、コードを見てみましょう。

    /// <summary>
    /// Groups and aggregates the sequence of elements.
    /// </summary>
    /// <typeparam name="TSource">The source type in the sequence.</typeparam>
    /// <typeparam name="TFirstKey">The first key type to group by.</typeparam>
    /// <typeparam name="TSecondKey">The second key type to rotate by.</typeparam>
    /// <typeparam name="TValue">The type of value that will be aggregated.</typeparam>
    /// <param name="source">The source sequence.</param>
    /// <param name="firstKeySelector">The first key selector.</param>
    /// <param name="secondKeySelector">The second key selector.</param>
    /// <param name="aggregator">The aggregating function.</param>
    /// <returns>A <see cref="Dictionary{TKey,TValue}" /> representing the pivoted data.</returns>    
    public static Dictionary<TFirstKey, Dictionary<TSecondKey, TValue>> Pivot<TSource, TFirstKey, TSecondKey, TValue>
        (this IEnumerable<TSource> source,
         Func<TSource, TFirstKey> firstKeySelector,
         Func<TSource, TSecondKey> secondKeySelector,
         Func<IEnumerable<TSource>, TValue> aggregator)
    {
        return source.GroupBy(firstKeySelector).Select(
            x => new
            {
                X = x.Key,
                Y = x.GroupBy(secondKeySelector).Select(
                    z => new { Z = z.Key, V = aggregator(z) }).ToDictionary(e => e.Z, o => o.V)
            }).ToDictionary(e => e.X, o => o.Y);
    }

関数が行うことは、TSource 型の IEnumerable を取り込み、アイテムをディクショナリにピボットし、定義した関数を使用してアイテムを集約することです。サンプルのデータ セットは、(Person という型の) 人の配列です。

        private static readonly Person[] people =
        new[]
        {
            new Person { Forename = "Matt", Surname = "Someone", Email = "matthew@somewhere.com", Age = 25, IsMale = true },
            new Person { Forename = "Chris", Surname = "Someone", Email = "chris@somewhere.com", Age = 28, IsMale = false },
            new Person { Forename = "Andy", Surname = "Someone", Email = "andy@somewhere.com", Age = 30, IsMale = true },
            new Person { Forename = "Joel", Surname = "Someone", Email = "joel@somewhere.com", Age = 30, IsMale = true },
            new Person { Forename = "Paul", Surname = "Someone", Email = "paul@somewhere.com", Age = 30, IsMale = true }
        };

そして最後に、テストを行います。

    /// <summary>
    /// Performs a pivot function on the sample array.
    /// </summary>
    [Test]
    public void Pivot()
    {
        /* Our sample data is an array of Person instances.
         * Let's organise it first by gender (IsMale), and then by Age.
         * Finally, we'll return a count. */
        var organised = people.Pivot(p => p.IsMale, p => p.Age, l => l.Count());

        Assert.IsTrue(organised.Count == 2, "More than two genders were returned.");
        Assert.IsTrue(organised[true].Count == 2, "More than two ages were returned for males.");
        Assert.IsTrue(organised[false].Count == 1, "More than 1 age was returned for females.");

        int count = organised[true][30];            
        Assert.IsTrue(count == 3, "There are more than 3 male 30 year olds in our data.");
    }

このテスト ケースで返されるのは Dictionary> インスタンスです。ブール値は IsMale グループ化の結果であり、サンプル データでは true と false の 2 つの項目を正しく返します。内部ディクショナリには、年齢のキーとカウントの値があります。私たちのテスト データでは、organized[true][30] はセット内の 30 歳のすべての男性を反映しています。

問題はピボット関数自体ではありませんが、何らかの理由で、NUnit テスト ランナーと Resharper のユニット テスト ランナーの両方でこれを実行すると、テストは失敗し、"int count = organized[true][ 30];". このテストをデバッグすると、値 3 が正しく返されます (サンプル データのように、30 歳の男性が 3 人います)。

何かご意見は?

4

1 に答える 1

0

VS 内から (外部プログラムとして) 実行するように NUnit を構成しようとしましたか? このようにして、NUint にテストを実行させることができます。デバッガーの下で

于 2009-12-11T13:52:08.610 に答える