سؤال

ولقد بدأت للتو لتنفيذ الاختبارات وحدة (باستخدام xUnit وموك) على مشروع أنشئت بالفعل من الألغام. ويستخدم المشروع على نطاق واسع حقن التبعية عبر الحاوية الوحدة.

ولقد الخدمتين A و B. خدمة A هو واحد يجري اختبارها في هذه الحالة. خدمة ليدعو B ويعطيها مندوب إلى وظيفة داخلية. ويستخدم هذا "رد" على أن تخطر وعندما تم تلقي رسالة أنه يجب التعامل معها.

وبالتالي المكالمات (حيث b هو مثيل خدمة B):

b.RegisterHandler(Guid id, Action<byte[]> messageHandler);

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

ويمكن أن يتم ذلك باستخدام موك؟ أي. يمكنني همية خدمة B، بحيث عندما يتم استدعاء RegisterHandler، يتم تمرير قيمة messageHandler إلى اختباري؟

وأو أحتاج لإعادة تصميم هذا؟ هل هناك أي أنماط التصميم وأرجو أن تستخدم في هذه الحالة؟ لا أحد يعرف أي موارد جيدة على هذا النوع من التصميم؟

هل كانت مفيدة؟

المحلول

ويمكنك الحصول على مثيل من رد (أو أي معلمة الإدخال الأخرى) باستخدام استدعاء (<م> تشابه الاسم عرضية ) الأسلوب على موك:

[TestMethod]
public void Test19()
{
    Action<byte[]> callback = null;

    var bSpy = new Mock<IServiceB>();
    bSpy.Setup(b => b.RegisterHandler(It.IsAny<Guid>(), It.IsAny<Action<byte[]>>()))
        .Callback((Guid g, Action<byte[]> a) => callback = a);

    var sut = new ServiceA(bSpy.Object);
    sut.RegisterCallback();

    Assert.AreEqual(sut.Do, callback);
}

وهذا يعمل عند تعريف ServiceA كما يلي:

public class ServiceA
{
    private readonly IServiceB b;

    public ServiceA(IServiceB b)
    {
        if (b == null)
        {
            throw new ArgumentNullException("b");
        }

        this.b = b;
    }

    public void RegisterCallback()
    {
        this.b.RegisterHandler(Guid.NewGuid(), this.Do);
    }

    public void Do(byte[] bytes)
    {
    }
}

نصائح أخرى

ونعم يمكنك إعداد الكائن موك للرد على العمليات المتوقعة وغير المتوقعة. وهنا البصرية وحدة ستوديو اختبار سبيل المثال ...

[TestMethod]
public void MyTest()
    {
      var moqObject = new Mock<ServiceB>();

      // Setup the mock object to throw an exception if a certain value is passed to it...
      moqObject.Setup(b => b.RegisterHandle(unexpectedValue).Throws(new ArgumentException());

      // Or, setup the mock object to expect a certain method call...
      moqObject.Setup(b => b.RegisterHandle(expectedValue));

      var serviceA = new ServiceA(moqObject.Object);

      serviceA.DoSomethingToTest();

      // This will throw an exception if an expected operation didn't happen...
      moqObject.VerifyAll();
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top