Moq: गैर-अप्रतिबंधित सदस्य पर अमान्य सेटअप: x => x.GetByTitle ("पीडीएफ")


111

निश्चित नहीं है कि मैं इसे कैसे ठीक कर सकता हूं, "GetByTitle" विधि पर एक इकाई परीक्षण करने की कोशिश कर रहा हूं

यहाँ मेरी परिभाषाएँ हैं:

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public IArticle GetByTitle(string title)
    {
        IQuery query = Session.CreateQuery("...")
        return query.UniqueResult<IArticle>();
    }
}

public interface IArticleDAO
{
    IArticle GetByTitle(string title);
}

अध्याय परीक्षा:

[Test]
public void can_load_by_title()
{
    _mockDaoFactory.Setup(x => x.GetArticleDao())
                                .Returns(_mockArticleDao.Object);
    _mockArticleDao.Setup(x => x.GetByTitle("some title"))
                                .Returns(article1.Object);

    _articleManager.LoadArticle("some title");

    Assert.IsNotNull(_articleManager.Article);
}

परीक्षण चलाने से मुझे त्रुटि मिलती है:

System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetByTitle("some title")

अपडेट करें

मेरी [Setup]तरह दिखता है:

[Setup]
public void SetUp()
{
     _mockDaoFactory = new Mock<IDaoFactory>();
     _mockArticleDao = new Mock<ArticleDao>();

     _articleManager = new ArticleManager(_mockDaoFactory.Object);    
}

2
क्या आप तुरंत _mockDaoFactoryऔर _mockArticleDaoकहीं? क्या आप क्लास या इंटरफ़ेस का मजाक उड़ाते हैं
टॉमस एशचन

हां, मैंने इंटरफ़ेस का उपयोग करके [सेटअप] में डीओफैक्टिक और मॉकार्टिकलडॉ का मजाक उड़ाया। डीएओ वर्ग का उपयोग करके किया गया था।
मर्बल्लाह

@tomas मैंने सेटअप कोड के साथ अपना प्रश्न अपडेट किया।
मर्बल्लाह

2
जैसा कि आप मेरे जवाब में देख सकते हैं, आपको इंटरफ़ेस को या तो मॉक करने की ज़रूरत है (यही वह है जो मैं सुझाता हूं) या GetByTitleविधि को चिह्नित करता हूं virtual
टॉमस असचन

यह भी दिखता है कि क्या आपके परीक्षण में पहली पंक्ति को सेटअप रूटीन में स्थानांतरित किया जा सकता है ...?
टॉमस असचन

जवाबों:


154

एक मॉक ऑब्जेक्ट के व्यवहार को नियंत्रित करने के लिए (Moq में, कम से कम), आपको या तो एक इंटरफ़ेस को मॉक करने की आवश्यकता है, या सुनिश्चित करें कि आप जिस व्यवहार को नियंत्रित करने की कोशिश कर रहे हैं वह वर्चुअल चिह्नित है। आपकी टिप्पणी में, मैं इसे समझता हूँ ताकि _mockArticleDaoइस तरह से कुछ किया जाए:

_mockArticleDao = new Mock<ArticleDAO>();

यदि आप इसे रखना चाहते हैं, तो आपको GetArticleविधि को चिह्नित करने की आवश्यकता है virtual:

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public virtual IArticle GetByTitle(string title)
    {
        // ...
    }
}

अन्यथा (यह वही है जो मैं सुझाता हूं), इसके बजाय इंटरफ़ेस को मॉक करें।

_mockArticleDao = new Mock<IArticleDAO>();

लेकिन जब से ArticleDAO जेनेरिक से विरासत में मिला ...., अगर मैं इंटरफ़ेस GenericNhibern में नकल करता हूं। उपलब्ध नहीं कराया जाएगा?
मर्बल्लाह

क्योंकि कारखाने से GetArticleDAO को कॉल करता है ArticleDAO नहीं IArticleDAO, b / c articleDAO भी एक अमूर्त वर्ग को बांधता है जिसमें निहर्नेट सामान होता है।
मर्बल्लाह

2
यदि आप इंटरफ़ेस को मॉक नहीं कर सकते हैं, तो आप गलत चीज़ का परीक्षण कर सकते हैं ... लेकिन फिर भी, विधि को चिह्नित करने से समस्या का समाधान हो जाएगा।
टॉमस असचन

+1 टॉमस, मुझे ctor में एक पैरामीटर इंजेक्ट करने की आवश्यकता है, इसलिए मेरे मामले में मुझे वास्तविक वर्ग का मज़ाक उड़ाना पड़ा और तरीकों को वर्चुअल में सेट करना पड़ा, क्योंकि आप इंटरफ़ेस के ctor में पैरामीटर इंजेक्ट नहीं कर सकते। क्या यह सही तरीका है?
होउमैन

4
@Kave: यदि आपको कंस्ट्रक्टर में कुछ इंजेक्ट करने की आवश्यकता है, तो आप निश्चित रूप से गलत चीज़ का परीक्षण कर रहे हैं। मॉक जो भी आप कंस्ट्रक्टर को देते हैं, उसका व्यवहार है और परीक्षण करें कि यह क्लास जिस तरह का व्यवहार करती है, वैसा ही करना चाहिए। यदि आपको आवश्यकता है, तो एक नया इंटरफ़ेस लिखें, जिसे आप सभी विधि हस्ताक्षरों तक पहुँचने के लिए "इंजेक्ट" प्रकार लागू करते हैं।
टॉमस अचान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.