Autofixture: اختياريا تعطيل التخزين المؤقت لـ AutoMoq؟

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

عند استخدام AutoConfiguredMoqCustomization ، يتم تخزين القيمة التي تم إرجاعها بواسطة الأداة المستخدمة مؤقتًا ، وسيتم إرجاع نفس القيمة في كل استدعاء (لست متأكدًا مما إذا كان هذا يتم في MockType. على الخط 104 هناك).

الطريقة الوحيدة التي اكتشفتها لتجاوزها هي تمرير مثيل Frozen من النموذج المعني في طريقة الاختبار ، وتجاوز الإعداد باستخدام func يستدعي التركيب:

someMock.Setup(it => it.SomeMethodReturningAString()).Returns(() => fixture.Create<string>())

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

enhancement good first issue

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

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

ال 14 كومينتر

كانت الفكرة وراء التخزين المؤقت لقيمة النتيجة هي جعل جميع الطرق _pure_ افتراضيًا ، وهو ما يعتبر ممارسة جيدة.

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

// This method will return the expected result *if* `GetInt` is pure.
int Double(IDependency dep) {
    return dep.GetInt() + dep.GetInt();
}

Assert.Equal(dep.GetInt * 2, Double(dep));

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

ومن ثم ، فإن التقصير في الوظائف البحتة كان منطقيًا بالنسبة لي عندما قمت بتطبيق هذه الميزة.

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

إذا كنت بحاجة إلى القيام بذلك لطريقة _one_ ، ولكن عبر اختبار متعدد ، فقد أضعه في IConfiguration قابل لإعادة الاستخدام.

إذا كنت تريد القيام بذلك لجميع الطرق ، عبر اختبارات متعددة ، فستحتاج إلى مزيد من العمل:

  • تحديد تطبيق جديد ReturnsUsingContext (IIRC ، يمكنك فقط نسخ التطبيق الحالي وإزالة السطر 104)
  • أعد تعريف MockVirtualMethodsCommand واستبدل المكالمة بـ ReturnsUsingContext باستدعاء طريقتك الجديدة.
  • أعد تعريف AutoConfiguredMoqCustomization واستبدل إنشاء مثيل MockVirtualMethodsCommand بإنشاء مثيل لفصلتك الجديدة.

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

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

هذه نقطة جيدة جدًا ، لم أفكر مطلقًا في Freeze بهذه الطريقة. إن تغيير سلوك التخصيص الآن سيكون بمثابة تغيير جذري ، أعتقد ... هل تعتقد أنه يجب تغييره في AutoFixture v4؟

هل هو سلوك قمنا بتوثيقه أو "وعدنا به" بطريقة ما في الاختبارات؟

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

نقطة عادلة. هل يمكن أن تكون قيمة تكوين قمنا بتعيينها على قيمة واحدة الآن ، ثم نبدلها عندما ننتقل إلى AutoFixture 4؟

متفق. في هذا السياق ، ماذا تقصد بالضبط ب "قيمة التكوين"؟ هل يكفي رفعه إلى قيمة ثابتة داخل فئة MockType ؟ على سبيل المثال ، private const bool cacheReturnValues = true ثم if(cacheReturnValues) /**/

أعترف أنه كان تعليقًا بعيد المنال ، لذلك لا أعرف ما إذا كان سيكون ممكنًا عمليًا بدون الكثير من التغييرات. ما قصدته ، رغم ذلك ، كان هذا:

andreasnilsen يود تغيير السلوك الآن ، لكننا قلقون من أنه سيكون تغييرًا قابلاً للتهيئة ،

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

يمكن أن يكون شيء مثل cacheReturnValues المنطقي إحدى طرق القيام بذلك ، ولكن علينا تمكين العملاء من تغيير القيمة ، لذلك لا يمكن أن تكون private .

(أيضًا ، ما لم نكن متأكدين تمامًا من أنه ستكون هناك قيمتان فقط بالضبط ، يجب أن نفكر في enum بدلاً من bool .)

آه ، اعتقدت في البداية أنك تعني بعض العلم الداخلي الذي كان من السهل اكتشافه وتغييره في الإصدار 4.

أول نهجين يتبادران إلى الذهن هما:

  • ما عليك سوى إضافة معامل منطقي (اختياري ، للتوافق مع الإصدارات السابقة) إلى المُنشئ AutoConfiguredMoqCustomization ، والذي سيتم نشره بعد ذلك إلى MockVirtualMethodsCommand وإلى MockType.ReturnsUsingContext الداخلي. هذا يبدو:

    1. قليلا معقد و

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

  • استخدم نمط كائن المعلمة لحل المشكلة (2) أعلاه.

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

كنت أفكر في شيء مثل استراتيجية ...

آه نعم بالطبع! أعتقد أنني كنت مهتمًا بـ "قيمة التكوين" ونسيت التراجع خطوة.

أنا آسف على الرد المتأخر ، لقد غمرتني - سألقي نظرة على هذا قريبًا وأعود باقتراح تصميم.

لقد أجرينا مؤخرًا إعادة هيكلة التخصيص لاستخدام الخصائص لتعديل التخصيص. من المحتمل ، يمكن التحكم في هذه الميزة كما يلي (ابحث عن اسم الإعداد الأفضل):
c# new AutoMoqCustomization { CacheCallResults = false }

تحت غطاء المحرك يمكننا تنفيذ ذلك من خلال استراتيجية مختلفة مثل تلك التي تم نصحها أعلاه.

وضع العلامات بعلامة قفزة ، حيث يجب أن يكون تنفيذ ذلك بسيطًا نسبيًا.

zvirja هل يمكنك مساعدتي قليلاً ويمكنني العمل على هذا. أنا فقط لا أعرف من أين أبدأ :)

micheleissa شكرا لاهتمامك! أود أن أقترح قراءة الكود المصدري AutoMoq وتصحيحه لفهم الآليات الداخلية. إنه صغير جدًا ، لذا لا ينبغي أن يستغرق الكثير من الوقت ...

إذا كان لديك سؤال أكثر تحديدًا ، فيرجى طرح 😉

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