2015-02-18 11 views
24

चूंकि मैंने अपनी डब्ल्यूसीएफ विधियों को असिनक में परिवर्तित कर दिया है, इसलिए मेरे यूनिट परीक्षण विफल हो गए हैं, और मैं उन्हें काम करने के लिए सही वाक्यविन्यास नहीं समझ सकता।कार्य के साथ Moq

Cllient प्रॉक्सी वर्ग

public interface IClientProxy 
{ 
    Task DoSomething(CredentialDataList credentialData, string store); 
} 

सेवा वर्ग

public class CredentialSync : ICredentialSync 
{ 
    private ICredentialRepository _repository; 

    private IClientProxy _client; 

    public CredentialSync() 
    { 
     this._repository = new CredentialRepository(); 
     this._client = new ClientProxy(); 
    } 

    public CredentialSync(ICredentialRepository repository, IClientProxy client) 
    { 
     this._repository = repository; 
     this._client = client; 
    } 

    public async Task Synchronise(string payrollNumber) 
    { 
     try 
     { 
      if (string.IsNullOrEmpty(payrollNumber)) 
      { 
       .... some code 
       } 
      else 
      { 
       CredentialDataList credentialData = new CredentialDataList(); 
       List<CredentialData> credentialList = new List<CredentialData>(); 

       // fetch the record from the database 
       List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber); 
       var pinData = this._repository.GetCredentialPinData(payrollNumber); 

       // get the stores for this employee 
       var storeList = data.Where(a => a.StoreNumber != null) 
        .GroupBy(a => a.StoreNumber) 
        .Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray(); 

       var credential = this.ExtractCredentialData(data, pinData, payrollNumber); 

       credentialList.Add(credential); 
       credentialData.CredentialList = credentialList; 

       foreach (var store in storeList) 
       {  
        //this line causes an Object reference not set to an instance of an object error 
        await _client.DoSomething(credentialData, store.StoreNumber); 

       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new FaultException<Exception>(ex); 
     } 
    } 

टेस्ट कक्षा

/// </summary> 
[TestClass] 
public class SynchTest 
{ 

    private Mock<ICredentialRepository> _mockRepository; 
    private Mock<IClientProxy> _mockService; 

    [TestInitialize] 
    public void Setup() 
    { 
     ... some setups for repository which work fine 
    } 

[TestMethod]  
    public async Task SynchroniseData_WithOneEmployee_CallsReplicateService() 
    { 
     this._mockService = new Mock<IClientProxy>(); 
     this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>())); 
     // arrange 
     string payrollNumber = "1"; 
     CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object); 

     // act 
     await service.Synchronise(payrollNumber); 

     // assert     
     this._mockService.VerifyAll(); 
    } 

erro आर जब ClientProxy.DoSomething कहा जाता है:

वस्तु संदर्भ एक वस्तु

मापदंडों दोनों ठीक हैं का एक उदाहरण के लिए सेट नहीं।

अगर मैं एक तुल्यकालिक विधि (सार्वजनिक शून्य DoSomething(...)) कोड ठीक काम करता है के लिए मेरे ClientProxy.DoSomething विधि कनवर्ट करते हैं, लेकिन मुझे लगता है कि आप इस की जरूरत है

उत्तर

54

DoSomething रिटर्न बजाय एक Task लौटने का null एसिंक्रोनस रूप से कहा जाता था, और इतने इसका इंतजार करते समय अपवाद प्राप्त करें। आपको मॉक बनाने के दौरान निर्दिष्ट करना होगा कि इसे Task वापस करना चाहिए।

इस मामले में ऐसा लगता है कि आप बस एक पहले ही पूरा काम लौट Task.FromResult का उपयोग कर कि दिखावटी सेटअप इस तरह दिखना चाहिए कर सकते हैं:

this._mockService.Setup(...).Returns(Task.FromResult(false)); 

नेट के अगले संस्करण की शुरुआत के साथ (4.6) आप Task.CompletedTask

+5

यह इस मामले में ध्यान दिया जाना चाहिए की Task.FromResult हिस्सा निकाल सकते हैं, झूठी सिर्फ एक प्लेसहोल्डर है, मूल्य झूठी वास्तव में नकली द्वारा नजरअंदाज कर दिया है, यह सिर्फ एक काम, किसी भी कार्य की जरूरत है , पूरा करना। यह वास्तव में झूठी जगह के बजाय "foo" हो सकता है ... – mcse3010

+0

@ mcse3010 वास्तव में। – i3arnon

+1

4.6 वाक्यविन्यास के लिए उपरोक्त, यह वास्तव में क्या है इसका संक्षिप्त और संकेतक है। – starmandeluxe

4

उपयोग कर सकते हैं मैं तुम्हें DoSomething नकली

से Task वापस जाने के लिए की जरूरत है
this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>())) 
           .Returns(Task.FromResult<int>(0)); 
+0

या मेरा पसंदीदा 'Returns (कार्य। डेले (0)); ' –

10

आप ReturnsAsync

this._mockService.Setup(...).ReturnsAsync(false) का उपयोग करके कोड में अव्यवस्था की मात्रा को कम कर सकते हैं;

इस तरह आप कोड