2009-05-19 14 views
6

मैं अपने नियंत्रकमैं एक ISingleResult कैसे moq कर सकते हैं? क्या मैं? या एक बेहतर तरीका है?

public ActionResult Index() 
{ 
    using (NorthwindDataContext db = new NorthwindDatacontext()) 
    { 
     var results = db.GetRecordSets(arg1, ....).ToList(); 
     // use results as list 
    } 

    return View(); 
} 

में इस तरह एक कार्रवाई विधि है और मैं इसे (हाँ, के बाद इसे बनाया गया था, इससे पहले कि नहीं ... लेकिन कोड इससे पहले कि मैं शुरू कर दिया लिखा गया था के लिए परीक्षण करना शुरू करना चाहता था TDD उपयोग करती हैं इसलिए ...)

और मैं पता लगा कि इस तरह के नियंत्रक को यह एक के रूप में एक संपत्ति जोड़ने

public delegate NorthwindDatacontext ContextBuilderDelegate(); 

public ContextBuilderDelegate ContextBuilder { get; set; } 

मैं इस तरह निर्माता कुछ में जोड़ सकते हैं ...

0,123,
ContextBuilder =() => new NorthwindDatacontext(); 

तो मुझे लगता है मैं कोई रास्ता नहीं इस का उपयोग करने के लिए मिला NorthwindDatacontext

var controller    = new MyController(); 
var mockDataContext   = new Mock<NorthwindDatacontext>(); 
controller.ContextBuilder =() => mockDataContext.Object; 

लेकिन ... का एक नकली के साथ ContextBuilder संपत्ति की स्थापना ActionMethod परीक्षण कर सकते हैं क्योंकि NorthwindDatacontext के सभी तरीकों returnType रूप ISingleResult का उपयोग करें और मैं नहीं कर सकते उस इंटरफ़ेस के साथ ऑब्जेक्ट बनाने का तरीका ढूंढें। मैं इस

var theResult     = new List<GetRecordSetsResult>(); 
// fill the data structure here with the provided result... 

mockDataContext.Setup(c => c. GetRecordSets()).Returns(theResult as 
              ISingleResult<GetRecordSetsResult>); 

की कोशिश की है, लेकिन यह काम नहीं करता है जब ISingleResult में बदल जाती है क्योंकि theResult रिक्त है।

क्या इस तरह से परीक्षण करने के लिए ISingleResult ऑब्जेक्ट बनाने का कोई तरीका है या मैं यहां काम करने का गलत तरीका कर रहा हूं? GetEnumerator() -

अग्रिम

+0

धन्यवाद, आपका प्रश्न और पहला जवाब वास्तव में मुझे समस्या हल करने में मदद करता है। – Odd

उत्तर

3

ToList() धन्यवाद IEnumerable के लिए एक विस्तार विधि है, जो, नकली करने के लिए आसान है, क्योंकि यह केवल एक ही सदस्य विधि है।

फिर भी आप NorthwindDataContext वर्ग मजाक समस्याएं हो रही हों, अगर इसकी तरीकों आभासी नहीं हैं ...

फिर भी, कि कैसे मैं अपने खिलौने के डिब्बे में एक ऐसी ही समस्या हल है, आशा है कि यह मदद करता है:

public class MyType 
{ 
    public virtual ISingleResult<int> ReturnSomeResult() { throw new NotImplementedException(); } 
} 

[TestMethod] 
public void TestMethod1() 
{ 
    var mockMyType = new Mock<MyType>(); 
    var mockSingleResult = new Mock<ISingleResult<int>>(); 
    IEnumerable<int> someEnumerable = new int[] {1,2,3,4,5}; 
    mockSingleResult.Setup(result => result.GetEnumerator()).Returns(someEnumerable.GetEnumerator()); 
    mockMyType.Setup(myType => myType.ReturnSomeResult()).Returns(mockSingleResult.Object); 

    Assert.AreEqual(15, mockMyType.Object.ReturnSomeResult().ToList().Sum()); 
} 
+0

महान उत्तर ... यही वह है जो मैं भी करूँगा। – womp

+1

क्षमा करें, मैं यहाँ मूर्ख की तरह महसूस करता हूं क्योंकि मैं नहीं देख सकता कि मैं अपनी समस्या का समाधान कैसे कर सकता हूं। मैं इसे एक अच्छा दृष्टिकोण देखता हूं लेकिन यह मुझे जो चाहिए उसे हल नहीं करता है। मैं रोब कॉनरी के एमवीसी स्टोरफ्रंट वीडियो में एक नज़र डाल रहा था और मैं रिपोजिटरी पैटर्न देख सकता हूं जो मुझे चाहिए लेकिन यह आसानी से लिंककॉक्ल डेटा संदर्भों के साथ लागू नहीं किया जा सकता है जैसा कि मैं देख सकता हूं। –

+0

महान उत्तर, मेरी समस्या हल हो गई। – Odd

5

मैंने एक कक्षा बनाई जिसने ISingleResult को लागू किया और बस इसमें एक सूची डाली। मैं इस प्रकार के कोडिंग के लिए बिल्कुल नया हूं, इसलिए जब यह मेरे लिए काम करता है, तो अपने जोखिम पर उपयोग करें (और यदि आप टिप्पणी पोस्ट करते हुए छेद देखते हैं)।

class SingleResult<T>:ISingleResult<T> 
{ 
    readonly List<T> _list = new List<T>(); 

    public void Add(T item) 
    { 
     _list.Add(item); 
    } 

    #region Interface Items 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public object ReturnValue { get { return _list; } } 

    public void Dispose() { } 

    #endregion 
} 

इसका उपयोग किसी नकली हिस्से में वापस आने के लिए किया जा सकता है। इस प्रकार मैंने इसका उपयोग राइनो मोक्स के साथ किया:

[TestMethod] 
public void TestSomething() 
{ 
    //Arrange 
    // Make a data context and DAL 
    var _ctx = MockRepository.GenerateMock<IDataClassesDataContext>(); 
    var someDALClass = new SomeDALClass(_ctx); 

    User testUser = UserObjectHelper.TestUser(); 
    SingleResult<User> userList = new SingleResult<User> { testUser }; 

    // Indicate that we expect a call the to sproc GetUserByUserID 
    _ctx.Expect(x => x.GetUserByUserID(testUser.UserID)).Return(userList); 

    //Act 
    someDALClass.UpdateUser(testUser); 

    //Assert 
    Assert.IsTrue(SomeTestCondition()); 
} 
+0

बहुत अच्छा, +1। मैं इस बदलाव का उपयोग कुछ बदलावों के साथ कर रहा हूं: 1. '_list'' ' 'सूची के बजाय' inumerable 'है। 2. मैं 'Add' विधि रखने के बजाय कक्षा कन्स्ट्रक्टर में संग्रह का उपयोग करने के लिए तैयार हूं। – Konamiman

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