2017-04-06 8 views
5

के साथ मेडियाटआर 3 का मज़ाक उड़ाते हुए हमने हाल ही में मेडियटआर का उपयोग करना शुरू कर दिया है ताकि हम डी-क्लटर नियंत्रक क्रियाओं को अनुमति दे सकें क्योंकि हम पोर्टल का सामना करने वाले बड़े ग्राहक को फिर से कारक बनाते हैं और इसे सभी को # में परिवर्तित करते हैं। इसके हिस्से के रूप में हम अपने यूनिट टेस्ट कवरेज को भी बढ़ा रहे हैं, लेकिन मेडिएटआर को नकल करने की कोशिश करते समय मैंने एक समस्या आई है।मोक

कमांड प्रक्रिया शुरू करने के लिए सामान का एक गुच्छा करता है और इसका एक हिस्सा अधिसूचना भेज रहा है। अधिसूचना को अपने ही हैंडलर द्वारा निपटाया जाता है और इसलिए अपने स्वयं के यूनिट परीक्षण के अधीन होगा, इसलिए मैं MediatR का नकल करना चाहता हूं ताकि this.mediator.Send(message) कॉल वास्तव में कुछ भी नहीं कर सके। हैंडलर एक वस्तु वापस करता है लेकिन हमें इस संदर्भ में इसके बारे में परवाह नहीं है, इसलिए सभी उद्देश्यों और उद्देश्यों के लिए हम इसे void रिटर्न के रूप में देख रहे हैं। मैं बस सत्यापित करना चाहता हूं कि Send को परीक्षण के हिस्से के रूप में एक बार बुलाया गया है। हालांकि, Send विधि NullReferenceException फेंक रही है और मुझे नहीं पता कि क्यों।

संस्करण 3 के अनुसार, MediatR अब Send, CancellationToken पर एक दूसरा वैकल्पिक पैरामीटर लेता है, और अभिव्यक्ति पेड़ों के लिए आपको स्पष्ट रूप से सेट करने की आवश्यकता होती है ताकि आपको एक मान निर्दिष्ट करना होगा। मुझे इससे पहले और मेरे दिमाग में इसका सामना नहीं हुआ है, मुझे लगता है कि यह समस्या का हिस्सा हो सकता है लेकिन यह मेरे हिस्से पर उलझन में हो सकता है।

यहां एक कट डाउन इलस्ट्रेशन है।

SUT

public class TransferHandler : IAsyncRequestHandler<TransferCommand, TransferResult> 
{ 
    private readonly IMediator mediator; 

    public TransferHandler(IMediator mediator) 
    { 
     this.mediator = mediator; 
    } 

    public async Task<TransferResult> Handle(TransferCommand message) 
    { 
     // Other stuff. 
     var notification = new TransferNotificationCommand() 
     { 
      ClientId = message.clientId, 
      OfficeId = message.OfficeId, 
      AuthorityFileId = letter?.Id 
     }; 

     await this.mediator.Send(notification); // <=== This is where we get a NullReferenceException, even though nothing is actually null (that I can see). 

     return new TransferResult() 
     { 
      Transfer = transfer, 
      FileId = letter?.Id 
     } 
    } 
} 

टेस्ट

public class TransferHandlerTests 
{ 
    [Theory] 
    [AutoData] 
    public async void HandlerCreatesTransfer(Mock<IMediator> mockMediator) 
    { 
     // Note that default(CancellationToken) is the default value of the optional argument. 
     mediator.Setup(m => m.Send(It.IsAny<TransferNotificationCommand>(), default(CancellationToken))).Verifiable("Notification was not sent."); 

     var handler = new TransferHandler(mediator.Object); 

     var actual = await handler.Handle(message); 

     mediator.Verify(x => x.Send(It.IsAny<CreateIsaTransferNotificationCommand>(), default(CancellationToken)), Times.Once()); 
    } 
} 

मैं क्या याद आ रही है? मुझे लगता है कि मैंने कहीं मौलिक गलती की है लेकिन मुझे यकीन नहीं है कि कहां है।

उत्तर

8

आपको Send विधियों के एसिंक ऑपरेशन की प्रतीक्षा को संभालने की आवश्यकता है क्योंकि वे कार्य वापस करते हैं।

/// <summary> 
/// Asynchronously send a request to a single handler 
/// </summary> 
/// <typeparam name="TResponse">Response type</typeparam> 
/// <param name="request">Request object</param> 
/// <param name="cancellationToken">Optional cancellation token</param> 
/// <returns>A task that represents the send operation. The task result contains the handler response</returns> 
Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default(CancellationToken)); 

/// <summary> 
/// Asynchronously send a request to a single handler without expecting a response 
/// </summary> 
/// <param name="request">Request object</param> 
/// <param name="cancellationToken">Optional cancellation token</param> 
/// <returns>A task that represents the send operation.</returns> 
Task Send(IRequest request, CancellationToken cancellationToken = default(CancellationToken)); 

इसका मतलब है कि आप async प्रक्रिया

mediator 
    .Setup(m => m.Send(It.IsAny<TransferNotificationCommand>(), It.IsAny<CancellationToken>())) 
    .ReturnsAsync(new Notification()) //<-- return Task to allow await to continue 
    .Verifiable("Notification was not sent."); 

//...other code removed for brevity 

mediator.Verify(x => x.Send(It.IsAny<CreateIsaTransferNotificationCommand>(), It.IsAny<CancellationToken>()), Times.Once()); 
+0

प्रवाह जारी रखने के लिए जैसे कि मैंने कहा अनुमति देने के लिए नकली वापसी एक काम करने की जरूरत है - यह कुछ मौलिक और मूर्ख होना ही था !! मैं मान रहा था कि चूंकि मुझे रिटर्न की परवाह नहीं थी, इसलिए मैं इसे छोड़ सकता था, जब वास्तव में मैंने मजाक को नहीं बताया कि क्या करना है तो कोई काम वापस नहीं किया गया था। अब सही समझ में आता है, धन्यवाद! मैंने आपका जवाब संपादित किया है हालांकि रिटर्न थोड़ा सा था। –

+1

@StevePettifer, मुझे अनिश्चित था कि आपकी प्रतिक्रिया OP में प्रदत्त कोड पर आधारित थी। आपका अपडेट सटीक है। – Nkosi

संबंधित मुद्दे