2009-02-25 14 views
12

मैं वास्तव में ताले के लिए नया हूं और एक मॉक ऑब्जेक्ट के साथ एक निजी क्षेत्र को बदलने की कोशिश कर रहा हूं। वर्तमान में निजी क्षेत्र का उदाहरण कन्स्ट्रक्टर में बनाया गया है। मेरे कोड लगता है कि ...मैं एक निजी क्षेत्र का नकल कैसे करूं?

public class Cache { 
    private ISnapshot _lastest_snapshot; 

    public ISnapshot LatestSnapshot { 
     get { return this._lastest_snapshot; } 
     private set { this._latest_snapshot = value; } 
    } 

    public Cache() { 
     this.LatestSnapshot = new Snapshot(); 
    } 

    public void Freeze(IUpdates Updates) { 
     ISnapshot _next = this.LastestSnapshot.CreateNext(); 
     _next.FreezeFrom(Updates); 
     this.LastestSnapshot = _next; 
    } 

} 

मुझे क्या करना कोशिश कर रहा हूँ एक इकाई परीक्षण है कि ISnapshot.FreezeFrom(IUpdates) दावा Cache.Freeze(IUpdates) के भीतर से कहा जाता है पैदा करते हैं। मुझे लगता है कि मुझे निजी क्षेत्र _latest_snapshot को नकली ऑब्जेक्ट (शायद गलत धारणा?) के साथ बदलना चाहिए। मैं इसके बारे में कैसे जा सकता हूं, जबकि पैरामीटर रहित कन्स्ट्रक्टर को बनाए रखना और LatestSnapshot के सेट को सार्वजनिक करने का सहारा नहीं ले रहा हूं?

यदि मैं परीक्षण को गलत तरीके से लिखने के बारे में पूरी तरह से जा रहा हूं तो कृपया भी बताएं।

ISnapshot.FreezeFrom का वास्तविक कार्यान्वयन स्वयं गहरे ऑब्जेक्ट ग्राफ के साथ अन्य विधियों का एक उत्तराधिकारी कहता है, इसलिए मैं ऑब्जेक्ट ग्राफ़ पर जोर देने के लिए उत्सुक नहीं हूं।

अग्रिम धन्यवाद।

उत्तर

16

मैं लगभग "Working Effectively with Legacy Code" से तकनीक का हवाला देते हुए हूँ:

  1. एक इकाई परीक्षण में उप-वर्ग अपने वर्ग और उस में एक नकली वस्तु के साथ अपने निजी चर को अधिक्रमित (एक सार्वजनिक सेटर जोड़कर या निर्माता में) । आपको शायद चर को संरक्षित करना होगा।
  2. इस निजी चर के लिए एक संरक्षित गेटर बनाएं, और इसे वास्तविक निजी चर के बजाय एक मॉक ऑब्जेक्ट वापस करने के लिए सबक्लास परीक्षण में ओवरराइड करें।
  3. ISnapshot ऑब्जेक्ट बनाने के लिए संरक्षित फैक्ट्री विधि बनाएं, और इसे वास्तविक के बजाए एक मॉक ऑब्जेक्ट का उदाहरण लौटने के लिए सबक्लास का परीक्षण करने में ओवरराइड करें। इस तरह से निर्माता को शुरुआत से सही मूल्य मिल जाएगा।
  4. पैरामीटरेट कन्स्ट्रक्टर ISnapshot का उदाहरण लेने के लिए।
4

मुझे नहीं लगता कि आपको निजी सदस्य चर का नकल करने की आवश्यकता होगी। मजाक करने का पूरा विचार नहीं है कि ऑब्जेक्ट के लिए सार्वजनिक इंटरफ़ेस अपेक्षित काम करता है? निजी चर कार्यान्वयन विवरण हैं जो मॉक्स से संबंधित नहीं हैं।

+4

यदि परीक्षण के तहत एक वर्ग एक निजी क्षेत्र का उपयोग करता है जो डेटाबेस का प्रतिनिधित्व करता है। मैं उस डेटाबेस फ़ील्ड का नकल कैसे करूं? – Vanuan

+0

आप भंडार पैटर्न, जो मूल रूप से, खाल इंटरफेस का एक सेट के पीछे डेटासंग्रह ताकि वे आसानी से मज़ाक उड़ाया जा सकता है और – Jason

+1

फिर भी परीक्षण किया पता करने के लिए प्राप्त करना चाहते हैं, तो आप उस मज़ाक उड़ाया भंडार कैसे का निर्माण और यह उपभोक्ता को पारित करते हैं? क्या आपको एक सेटर या कन्स्ट्रक्टर पैरामीटर चाहिए? – Vanuan

3

मुझे यकीन नहीं है कि आप ऐसा कर सकते हैं। यदि आप _next का परीक्षण करना चाहते हैं तो आपको शायद इसे पैरामीटर के रूप में पास करना होगा और फिर अपने यूनिट परीक्षण पास में एक मॉक ऑब्जेक्ट में जाना होगा जिसे आप उम्मीद का उपयोग करके परीक्षण कर सकते हैं। अगर मैं मोक में ऐसा करने की कोशिश कर रहा था तो मैं यही करूँगा।

मैं क्या Moq ढांचे आज़मा सकते हैं का एक उदाहरण के रूप में:

Mock<ISnapshot> snapshotMock = new Mock<ISnapshot>(); 
snapshotMock.Expect(p => p.FreezeFrom(expectedUpdate)).AtMostOnce(); 
Cache c = new Cache(snapshotMock.Object); 
c.Freeze(expectedUpdate); 

नोट: मैं ऊपर कोड को संकलित करने के प्रयास नहीं किया है। यह सिर्फ एक उदाहरण देने के लिए है कि मैं इसे हल करने के तरीके कैसे प्राप्त करूंगा।

1

यह उत्तर सरल हो सकता है, लेकिन कोड को देखकर, क्या कोई तरीका है जिसमें ISnapshot.FreezeFrom(IUpdates) कहा जा रहा है? लगता है जैसे आप कुछ ऐसा करना चाहते हैं जो हमेशा सत्य रहेगा।

जेसन कहते हैं, मजाक स्थितियों के लिए है, जहां अपने वर्ग SomeInterface पर निर्भर करता है यह काम है करने के लिए, और आप से जो भी SomeInterface के कार्यान्वयन आप वास्तव में क्रम में उपयोग अलगाव में YourClass परीक्षण करना चाहते हैं।

+0

यदि आप इसे पसंद करते हैं, तो इसे ऊपर उठाएं :) – Jason

1

सवाल पूछने के लिए है: अगर यह काम बाहर से दिखाई देने प्रभाव क्या हैं?

क्या उन सभी स्नैपशॉट्स का क्या होगा? कन्स्ट्रक्टर में कहें कि एक विकल्प बाहर से अपने पहले स्नैपशॉट के साथ कैश को शुरू करने का विकल्प हो सकता है। एक और हो सकता है कि यह स्नैपशॉट कॉल करे जो कैश के बाहर मायने रखता है। यह इस बात पर निर्भर करता है कि आप क्या करते हैं।

1

यह प्रतिक्रिया करने के लिए बहुत देर हो चुकी हो सकता है। वैसे भी। मुझे भी इसी तरह की समस्या थी।

public class Model 
{ 
    public ISomeClass XYZ{ 
     get; 
     private set; 
     } 
} 

मैं अपने परीक्षण मामले में XYZ का मान सेट करने की आवश्यकता है। मैंने इस syntex का उपयोग कर समस्या का समाधान किया।

Expect.Call(_model.XYZ).Return(new SomeClass()); 
_repository.ReplayAll(); 

मामले में उपरोक्त जैसा कि नीचे दिखाया इस

Expect.Call(_cache.LatestSnapshot).Return(new Snapshot()); 
_repository.ReplayAll(); 
-2

बारी कैश की तरह यह कर सकते हैं किसी टेम्प्लेट में।

template <typename T=ISnapshot> 
public class Cache { 
    private T _lastest_snapshot; 

    public T LatestSnapshot { 
     get { return this._lastest_snapshot; } 
     private set { this._latest_snapshot = value; } 
    } 

    public Cache() { 
     this.LatestSnapshot = new Snapshot(); 
    } 

    public void Freeze(IUpdates Updates) { 
     T _next = this.LastestSnapshot.CreateNext(); 
     _next.FreezeFrom(Updates); 
     this.LastestSnapshot = _next; 
    } 

} 

उत्पादन कोड में कार्य करें:

Cache<> foo;//OR 
Cache<ISnapshot> bar; 

परीक्षण कोड में कार्य करें:

Cache<MockSnapshot> mockFoo; 
+0

गलत भाषा: सी #, सी ++ नहीं – skolima

0

आप शायद, इस तरह अपनी कक्षा refactor करने के क्रम में के लिए इसके साथ इंजेक्ट किया जा करना होगा ISnapshot के लिए एक अलग निर्भरता। आपकी कक्षा एक ही काम करने के लिए रहेगी।

public class Cache { 
private ISnapshot _lastest_snapshot; 

public ISnapshot LatestSnapshot { 
    get { return this._lastest_snapshot; } 
    private set { this._latest_snapshot = value; } 
} 

public Cache() : this (new Snapshot()) { 
} 

public Cache(ISnapshot latestSnapshot) { 
    this.LatestSnapshot = latestSnapshot; 
} 

public void Freeze(IUpdates Updates) { 
    ISnapshot _next = this.LastestSnapshot.CreateNext(); 
    _next.FreezeFrom(Updates); 
    this.LastestSnapshot = _next; 
} 

} 
0

आप बस अपनी मज़ाक उड़ाया वर्ग उदाहरण के साथ कैश करने के लिए "setSnapshot (ISnapshot)" विधि जोड़ सकते हैं।

तुम भी एक निर्माता है कि ISnapshot लेता है जोड़ सकते हैं।

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