2010-03-29 11 views
5

मैं IPrincipal पर लिखे गए एक विस्तार विधि के लिए कुछ यूनिट परीक्षण लिख रहा हूं। सहायता के लिए, सहायक वर्गों के एक जोड़े (इंटरफेस की नहीं लागू सदस्यों के लिए कुछ कोड संक्षिप्तता के लिए हटा दिया गया है) बनाया है:आप केवल पढ़ने वाले सदस्य वाले इंटरफ़ेस के लिए यूनिट-परीक्षण स्टब कैसे बनाते हैं?

public class IPrincipalStub : IPrincipal 
{ 
    private IIdentity identityStub = new IIdentityStub(); 

    public IIdentity Identity 
    { 
     get { return identityStub; } 
     set { identityStub = value; } 
    } 
} 

public class IIdentityStub : IIdentity 
{ 
    public string Name { get; set; } // BZZZT!!! 
} 

हालांकि, IIdentity इंटरफ़ेस में Name संपत्ति केवल पढ़ने के लिए किया जाता है (IIDentity इंटरफ़ेस एक गेटर निर्दिष्ट करता है लेकिन नाम संपत्ति के लिए एक सेटटर नहीं)।

इंटरफ़ेस ने इसे केवल पढ़ने-योग्य संपत्ति के रूप में परिभाषित करने के लिए परीक्षण उद्देश्यों के लिए अपनी स्टब ऑब्जेक्ट में नाम संपत्ति कैसे सेट कर सकता हूं?

+0

कन्स्ट्रक्टर? i.e 'IIdentityStub' में एक पैरामीटरयुक्त कन्स्ट्रक्टर होगा जो पैरामीटर के रूप में नाम लेता है। – shahkalpesh

+0

क्या आपका "BZZZT" संकलित त्रुटि का संदर्भ देता है? मैं आपके नमूने को ठीक से संकलित करने में सक्षम था (पहचान संपत्ति पर डब्ल्यू/अर्ध-कॉलन, जो है)। – micahtan

+0

@micahtan: हाँ, लेकिन जब आप इसके खिलाफ एक परीक्षण लिखने का प्रयास करते हैं, और परीक्षण में 'नाम' का मूल्य निर्धारित करते हैं, तो संकलक शिकायत करेगा कि 'नाम' केवल पढ़ने के लिए है, क्योंकि' नाम 'संपत्ति ' IIDentity' में एक सेटर परिभाषित नहीं है। –

उत्तर

3

आप सी # की ऑटो-प्रॉपर्टी सुविधा का उपयोग कर रहे हैं, लेकिन इसके बजाय आपको मैन्युअल मार्ग जाना चाहिए और संपत्ति के लिए बैकिंग फ़ील्ड बनाना चाहिए। एक बार आपके पास बैकिंग फ़ील्ड हो जाने पर आप कन्स्ट्रक्टर में अपना मान सेट कर सकते हैं (या इसे सार्वजनिक क्षेत्र बना सकते हैं और ऑब्जेक्ट के बाद इसे सेट कर सकते हैं, लेकिन यह थोड़ा उलझन वाला है)। एक मजाक/अलगाव ढांचे का उपयोग -

public class IIdentityStub : IIdentity{ 
    private string _name; 

    public IIdentityStub(string name){ 
     _name = name; 
    } 

    public string Name { get { return _name; } } 
} 
+0

और यदि मान कन्स्ट्रक्टर के माध्यम से सेटटेबल नहीं है, तो आपको अपने डिज़ाइन में कोई समस्या है। –

+0

उत्कृष्ट, धन्यवाद। –

+0

@ रॉबर्ट हार्वे: कोई समस्या नहीं सर। –

1

मैं NMock

+1

सच है, लेकिन मुझे लगा कि मैं बेहतर सीखूंगा कि पहले अपने स्वयं के स्टब्स कैसे लिखें। –

2

मैं juharr से सहमत की तरह एक नकली पुस्तकालय का उपयोग करें। मैं Moq की सिफारिश करता हूं।

निम्नलिखित प्रिंट होगा "रॉबर्ट":

using System; 
using System.Security.Principal; 
using Moq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var mockIdentity = new Mock<IIdentity>(); 
      var mockPrincipal = new Mock<IPrincipal>(); 

      mockIdentity.SetupGet(x => x.Name).Returns("Robert"); 
      mockPrincipal.SetupGet(x => x.Identity).Returns(mockIdentity.Object); 

      IPrincipal myStub = mockPrincipal.Object; 

      Console.WriteLine(myStub.Identity.Name); 
     } 
    } 
} 

संपादित करें: लेकिन आप हाथ से यह करने के लिए ...

using System; 
using System.Security.Principal; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main() 
     { 
      IIdentity identity = 
       new IdentityStub 
        { 
         Name = "Robert", 
         AuthenticationType = "Kerberos", 
         IsAuthenticated = true 
        }; 

      IPrincipal principal = new PrincipalStub(identity); 

      Console.WriteLine(principal.Identity.Name); // Robert 
      Console.WriteLine(principal.IsInRole(PrincipalStub.ValidRole)); // True 
      Console.WriteLine(principal.IsInRole("OtherRole")); // False 
     } 
    } 

    public class PrincipalStub : IPrincipal 
    { 
     public const string ValidRole = "TestRole"; 

     public PrincipalStub(IIdentity identity) 
     { 
      Identity = identity; 
     } 

     public IIdentity Identity { get; private set; } 

     public bool IsInRole(string role) 
     { 
      return role == ValidRole; 
     } 
    } 

    public class IdentityStub : IIdentity 
    { 
     public string Name { get; set; } 
     public string AuthenticationType { get; set; } 
     public bool IsAuthenticated { get; set; } 
    } 
} 

(ऊपर नहीं एक है चाहते हैं यूनिट टेस्ट, थोड़ा निर्भरता इंजेक्शन का उपयोग करके हाथ से लुढ़का हुआ स्टब्स का एक उदाहरण।)