Nunit: دعم معلمات النوع العام لـ TestCaseSourceAttribute

تم إنشاؤها على ١٥ نوفمبر ٢٠١٧  ·  4تعليقات  ·  مصدر: nunit/nunit

أنا أعمل على بعض حالات الاختبار التي قد تكون مصممة بشكل أفضل باستخدام الأدوية الجنيسة. أحاول استخدام TestCaseSource مع العديد من التركيبات المختلفة للأنواع.

المشكلة التي أواجهها هي استخدام الانعكاس في اختباراتي لاستدعاء طريقة اختبار عامة أستخدمها للتحقق من صحة الكائن.

[TestFixture]
public class SomeTests
{
    public static IEnumerable<TestCaseData> TestCases()
    {
        yield return
            new TestCaseData(
                typeof(Foo),
                typeof(Bar),
                Generator.Foo,
                Assertions.Foo);
        yield return
            new TestCaseData(
                typeof(Bar),
                typeof(Foo),
                Generator.Bar,
                Assertions.Bar);
    }

    [TestCaseSource(nameof(TestCases))]
    public void CheckSomeTypes(
        Type sourceType,
        Type destinationType,
        TSource source,
        Action<object, object> assert)
    {
        GetType()
            .GetMethod(nameof(CheckSomeTypesImpl), BindingFlags.Public | BindingFlags.Instance)
            .MakeGenericType(new[] { sourceType, destinationType })
            .Invoke(this, new object[] { source, assert });
    }

    public void CheckSomeTypesImpl<TSource, TDestination>(
        TSource source,
        Action<TSource, TDestination> assert)
    {
        var destination = Mapper.Map<TSource, TDestination>(source);

        // Assert are equiviliant
        assert(source, destination);
    }
}

ومع ذلك ، أعتقد أن التصميم التالي قد يضيف قيمة في هذه الحالة:

[TestFixture]
public class SomeTests
{
    public static IEnumerable<TestCaseData> TestCases()
    {
        yield return
            new TestCaseData(
                typeof(Foo),
                typeof(Bar),
                Generator.Foo,
                Assertions.Foo);
        yield return
            new TestCaseData(
                typeof(Bar),
                typeof(Foo),
                Generator.Bar,
                Assertions.Bar);
    }

    [TestCaseSource(nameof(TestCases))]
    public void CheckSomeTypes<TSource, TDestination>(
        TSource source,
        Action<TSource, TDestination> assert)
    {
        var destination = Mapper.Map<TSource, TDestination>(source);

        // Assert are equiviliant
        assert(source, destination);
    }
}

public class Foo
{
    public string Qux { get; set; }
}

public class Bar
{
    public string Qux { get; set; }
}

public static class Generator
{
    public static Foo Foo =>
        new Foo { Qux = "TestTestTest" };
    public static Bar Bar =>
        new Foo { Bar = "AnotherAnotherAnother" };
}

public static class Mapper
{
    // Generic mapper function
    public static TDestination Map<TSource, TDestination>(TSource source)
    {
        if (typeof(TSource) == typeof(Foo))
        {
            return Map((Foo) source);
        }

        if (typeof(TSource) == typeof(Bar))
        {
            return Map((Bar) source);
        }

        throw new NotImplementedException($"No mapping for {typeof(TSource).FullName}.");
    }

    public static Foo Map(Bar bar)
    {
        return new Foo { Qux = bar.Qux };
    }

    public static Bar Map(Foo foo)
    {
        return new Bar { Qux = foo.Qux };
    }
}

public static class Assertions
{
    public static Action<Foo, Bar> Foo =>
        (foo, bar) => Assert.AreEqual(foo.Qux, bar.Qux);
    public static Action<Bar, Foo> Bar =>
        (bar, foo) => Assert.AreEqual(bar.Qux, foo.Qux);
}

لقد قمت بعمل ملحقات لـ TestCaseSourceAttribute محليًا لدعم هذا.

هل هذا شيء مفتوح للمساهمة؟ أريد توضيح التصميم أولاً قبل إنشاء العلاقات العامة.

design enhancement

التعليق الأكثر فائدة

يمكن أن يعمل أيضا. @ nunit / framework-team ، هل وجد أي شخص آخر هذا الموضوع مثيرًا للاهتمام؟

ال 4 كومينتر

هل هذا شيء مفتوح للمساهمة؟ أريد توضيح التصميم أولاً قبل إنشاء العلاقات العامة.

شكرًا جزيلاً لبدء المحادثة وتقديم المساعدة لك. نريد توضيح التصميم قبل إنشاء العلاقات العامة أيضًا. = D من المحتمل أن ينتهي الأمر بفتح باب المساهمة قريبًا!

السؤال نفسه ولكن مقابل TestCaseAttribute ، وليس TestCaseSourceAttribute : https://github.com/nunit/nunit/issues/1215
الاستدلال فقط: https://github.com/nunit/nunit/issues/150

أنا مضطر بالفعل لكتابة رمز دون المستوى الأمثل اليوم ، لذلك أريد ذلك تمامًا.

في مُنشئ TestCaseData ، هل تعتقد أن هناك طريقة لتمييز قيم Type التي تملأ معلمات الطريقة العامة من قيم Type التي تملأ معلمات الطريقة العادية؟

لقابلية الاكتشاف: ماذا عن new TestCaseData<T1, T2>(ordinaryArg1, ordinaryArg2)?

أو هذا ، مما يسمح لنا بتجنب الإعلان عن فئات N TestCaseData جديدة:
TestCaseData.Create<T1, T2>(ordinaryArg1, ordinaryArg2, ordinaryArg3)

ماذا عن استخدام طريقة مثل TestCaseData.GenericsArgs (params Type [] generics) المشابهة لطريقة الإرجاع.

يمكن أن يعمل أيضا. @ nunit / framework-team ، هل وجد أي شخص آخر هذا الموضوع مثيرًا للاهتمام؟

تم وضع علامة على هذه المشكلة على أنها فكرة / تصميم / مناقشة ولكن لم يكن لديها مساهمات منذ سنوات ، لذا فأنا أختم. إذا كان أي شخص مهتمًا بالعمل على هذه الفكرة ، فأعلن عن اهتمامك وسيفكر الفريق في إعادة فتحها.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات