كيفية التحقق من طريقة أخرى في فئة كانت تسمى باستخدام موك
-
06-07-2019 - |
سؤال
وهذا يبدو وكأنه شيء بسيط ولكن أنا لا يمكن أن يبدو للحصول على عمل.
ولدي فئة مع طريقة حفظ يدعو ببساطة ShouldBeCalled طريقة أخرى (). أريد أن تحقق إذا أدعو حفظ () أن طريقة أخرى ShouldBeCalled () يتم تنفيذه مرة واحدة على الأقل. اعتقدت أنني يمكن أن تفعل ما يلي.
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
ولكن أحصل على استثناء "الاحتجاج المتوقع على وهمية مرة واحدة على الأقل، ولكن لم يكن أداؤها: س => x.ShouldBeCalled ()"
وانها مجرد تخمين ولكن هل موك تجاوز طريقة حفظ () مع نسخة هو نفسه الذي يتجاهل أي شيء لدي داخل حفظ الهدف الحقيقي والأسلوب ().
المحلول
وكنت تواجه هذه المشكلة لأنك تسخر ما تختبره. هذا لا معنى له.
وأنت صحيح أن موك سيحل محل تنفيذ الأسلوب الخاص بك مع تلقاء نفسها. ويفترض أن السبب لك استخدام موك أن يسخر الأشياء <م> درجة التي تختبر م> المكالمات، وليس للدرجة التي تختبر نفسها.
وهذا الاختبار سيكون مناسبا إذا تم تصميم التعليمات البرمجية هكذا:
public class ClassA
{
BusinessLogicClass bl;
public ClassA(BusinessLogicClass bl)
{
this.bl = bl;
}
public void Save()
{
bl.ShouldBeCalled();
}
}
public class BusinessLogicClass
{
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
وهنا هو الاختبار الصحيح من هذه الطريقة الآن:
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_ShouldCallShouldBeCalled()
{
//Arrange
var mockBLClass = new Mock<BusinessLogicClass>();
mockBLClass.Setup(x => x.ShouldBeCalled()).Verifyable();
//Act
ClassA classA = new ClassA(mockBLClass.Object);
classA.Save();
//Assert
mockBLClass.VerifyAll();
}
}
والدرس الرئيسي هنا هو أنك <م> وهمية / كعب ما يحتاج الاختبار الخاصة بك لتشغيل م>، وليس ما تختبره نفسها.
ويساعد هذا الأمل، أندرسون
نصائح أخرى
وحاول استخدام CallBase = صحيح ثم كاذبة. ركضت الشفرة ويعمل.
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true;
mockClassA.Object.Save();
mockClassA.CallBase = false;
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
نعم، يمكن القيام بذلك. ومع ذلك، تحتاج إلى إضافة سطر من التعليمات البرمجية لدينا موك المسار أم لا طريقة ShouldBeCalled كان يسمى في الواقع.
وشيء من هذا القبيل ما يلي ستعمل:
var mockClassA = new Mock<ClassA>();
mockClassA.Setup(x => x.ShouldBeCalled()).Verifiable();
mockClassA.Object.Save();
mockClassA.Verify(x => s.ShouldBeCalled(), Times.AtLeastOnce());
وطريقة الإعداد يضع التوقعات. عند استدعاء تحقق، تسألون موك للتحقق هذه التوقعات. إذا لم يكن لإجراء مكالمة الإعداد لإنشاء التوقعات للأسلوب ShouldBeCalled، ثم موك لا يعتبرون أن يكون تتبعها وبالتالي ستفشل الثابت عند محاولة التحقق من ذلك.
ويمكنك كعب الأساليب في نظام تحت الاختبار باستخدام CallBase
أ >.
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
// Arrange
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true; // this will call real methods unless the method is mocked/stubbed.
mockClassA.Setup(a => a.ShouldBeCalled());
// Act
mockClassA.Save();
// Assert
mockClassA.Verify(a => a.ShouldBeCalled(), Times.Once());
}
}