Autofixture: فشل تطبيق التخصيصات من الفئة الأساسية أو الواجهة في 4.0.0-rc1 (الانحدار)

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

نجحت الاختبارات التالية في AutoFixture 3.51.0 لكنها فشلت في 4.0.0-rc1 :
(حتى في أحدث التزام في الماجستير: c856cd6 )

ج #
[حقيقة]
يجب تطبيق الفراغ العام
{
var fixture = تركيبات جديدة () ؛
المباراة(ج => ج بدون (bc => bc.Id)) ؛
var res = fixture.Create. فار ريس = تركيبات() ؛
تأكيد المساواة (0 ، الدقة ، معرف) ؛
}

[حقيقة]
يجب تطبيق الفراغ العام
{
var fixture = تركيبات جديدة () ؛
المباراة(ج => ج بدون (bc => bc.Id)) ؛
var res = fixture.Create. فار ريس = تركيبات() ؛
تأكيد المساواة (0 ، الدقة ، معرف) ؛
}

الواجهة العامة IInterface
{
معرف int {get؛ يضع؛ }
}

فئة عامة BaseClass
{
معرف int العامة {get؛ يضع؛ }
}

فئة عامة ImplClass: BaseClass و IInterface
{

}
""

question

ال 10 كومينتر

شكرا لطرح السؤال. حسنًا ، هذا هو التغيير المطلوب وقد تم تطبيقه عن قصد.

في السابق كانت لدينا مشكلة عندما يمكن أن يؤثر تخصيص نوع فرعي واحد على نوع فرعي آخر. على سبيل المثال:

ج #
فئة Base {public string Common {get؛ يضع؛ }}
فئة Child1: Base {}
فئة Child2: Base {}

[حقيقة]
ضمان الفراغ العام
{
var fixture = تركيبات جديدة () ؛
المباراة(c => c.With (x => x.Common، "dummy")) ؛

var result = fixture.Create<Child2>();

Assert.NotNull(result.Common);

}


In the v3 this test failed, causing a lot of confusion to people. As you might imagine, the scenarios were more complicated and it was very non-obvious why the particular members are not initialized. 

For instance, the following code will not work, which again proves that API is not designed for that.
```c#
fixture.Customize<Base>(c => c.With(x => x.Common, "foo"));

لذلك ، من أجل إصلاح هذه المشكلة ، قمنا بتغيير النهج ، بحيث لا يمكن أن يؤثر التخصيص الآن على الأنواع الأخرى ، حتى لو كانت تنتمي إلى نفس خط الوراثة. كما قد ترى في تلك العلاقات العامة ، فقد أصلحت مجموعة من مشكلات قابلية الاستخدام وأضفت مزيدًا من الوضوح (في حين أن التغيير ينكسر بالفعل).

إذا كنت لا تزال تريد حذف خصائص القاعدة / الواجهة ، فيمكنك استخدام المقتطف التالي:
ج #
فئة خاصة SameProperty
{
خاص للقراءة فقط اكتب _declaringType؛
سلسلة للقراءة فقط الخاصة _name؛

public SamePropertySpecification(Type declaringType, string name)
{
    _declaringType = declaringType;
    _name = name;
}

public bool IsSatisfiedBy(object request)
{
    if (request is PropertyInfo pi)
    {
        return pi.DeclaringType == this._declaringType &&
               pi.Name.Equals(this._name, StringComparison.Ordinal);
    }

    return false;
}

}

[حقيقة]
اختبار الفراغ العام
{
var fixture = تركيبات جديدة () ؛

fixture.Customizations.Add(new Omitter(new SamePropertySpecification(typeof(Base), nameof(Base.Common))));

var result = fixture.Create<Child1>();
Assert.Null(result.Common);

}
""

إذا كنت بحاجة إلى هذه الميزة بشكل متكرر ، فيمكنك إنشاء طريقة التمديد الخاصة بك مقابل fixture . ومع ذلك ، سأصوت لعدم وجود مثل هذه الميزة خارج الصندوق ، لأنها تبدو مربكة للغاية.

حسنًا ، من الجيد معرفة أنه كان مقصودًا. أوافق بالتأكيد على أنه كان محيرًا ، ولكن إذا كان من الممكن تطبيقه بشكل صريح ، فهذه ميزة رائعة. سنحاول المقتطف الخاص بك (ومن المحتمل أن يجعل طريقة التمديد).

بالمناسبة: هل هذا شيء تريد إضافته إلى قائمة التغييرات العاجلة؟ قد يمنع طرح نفس السؤال.

لا توجد طريقة للاشتراك في السلوك القديم لتخصيص واحد لجميع التخصيصات ، أليس كذلك؟

هل هذا شيء تريد إضافته إلى قائمة التغييرات العاجلة؟

حسنًا ، تم ذكره في قسم إصلاحات الأخطاء . هذا في الواقع ليس تغييرًا جذريًا ، حيث لم يتم ذكر السلوك السابق مطلقًا على أنه "ميزة". بدلا من ذلك ، كان هذا من الآثار الجانبية غير المرغوب فيها وتم القضاء عليه في النهاية

لا توجد طريقة للاشتراك في السلوك القديم لتخصيص واحد لجميع التخصيصات ، أليس كذلك؟

لا ، لا توجد مثل هذه الطريقة التي أؤمن بها حيث أنني قمت بإعادة صياغة النهج بالكامل.

يرجى اختبار المقتطف وإذا كان يعمل - لا تتردد في إغلاق المشكلة. أو إعلامي إذا كان لديك المزيد من الأسئلة 😃

لقد قمت بتعديلها بحيث تعمل أيضًا للواجهات وقمت بعمل طريقة تمديد بحيث يمكن استخدامها في Fixture.Customize(...) '. أشعر بقليل من الاختراق أكثر مما أرغب ، خاصة وأن الطريقة التي عملت بها في الإصدار 3 كانت مثالية بالنسبة لنا. ولكن نظرًا لأن حالة الاستخدام الوحيدة لدينا هي حذف الخصائص وأنها (والأهم) تعمل فإنها ستفي بالغرض. شكرا!

nphmuller آسف لأنني كسرت

لا لوم على الإطلاق. افهم أسبابك تمامًا وحتى توافق. فقط تمتص بالنسبة لي 😉

قد يغوص في المشكلة لاحقًا لمعرفة ما إذا كانت هناك طريقة أكثر إتقانًا. في الوقت الحالي من الغرامة.

فقط بدافع الفضول - ما هي حالتك الحقيقية لاستخدام ذلك؟ لأنني لم ألبي حاجة في مثل هذا النوع من الوظائف .. عادة ، عندما أكتب اختبارًا ، أحتاج إلى تخصيص نوع معين فقط ، بدلاً من تكوين نوع القاعدة أو الواجهة. هل تكتب نوعًا من التخصيص العالمي؟

في هذه الحالة ، نستخدم AutoFixture كمولد بيانات اختبار لاختبارات تكامل Entity Framework.

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

على سبيل المثال ، إحدى هذه الخصائص هي من قام المستخدم بإنشاء الكائن. هذه الخاصية ليست مثيرة للاهتمام بالنسبة لمعظم الاختبارات ، وإذا تم إنشاؤها ، فسيؤدي ذلك إلى إنشاء رسم بياني ضخم (تحتوي فئة المستخدم أيضًا على العديد من خصائص التنقل) والتي يجب إنشاؤها وإدراجها في قاعدة البيانات. هذا من شأنه أن يجعل الاختبار بطيئًا أو حتى يفشل عند مستوى ديسيبل لأنه لم يكن من المفترض إدخال الكائن بهذه الطريقة.

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

nphmuller شكرًا للتوضيح ، أصبح واضحًا الآن 😉 نعم ، يبدو أن السيناريو منطقي ، لكن يجب أن أعترف أنه يبدو شيئًا نادرًا ما تحتاجه.

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

القضايا ذات الصلة

Eldar1205 picture Eldar1205  ·  5تعليقات

zvirja picture zvirja  ·  4تعليقات

ploeh picture ploeh  ·  7تعليقات

josh-degraw picture josh-degraw  ·  4تعليقات

Ridermansb picture Ridermansb  ·  4تعليقات