আমি কীভাবে একটি এক্সটেনশন পদ্ধতি উপহাস করার জন্য মোক ব্যবহার করব?


87

আমি একটি পরীক্ষা লিখছি যা কোনও এক্সটেনশন পদ্ধতির ফলাফলের উপর নির্ভর করে তবে আমি চাই না যে এই এক্সটেনশন পদ্ধতির ভবিষ্যতের ব্যর্থতা এই পরীক্ষাটি কখনও ভেঙে ফেলুক। ফলাফলটিকে মশকরা করা সুস্পষ্ট পছন্দ বলে মনে হয়েছিল তবে মোক স্থিতিশীল পদ্ধতির (কোনও এক্সটেনশন পদ্ধতির প্রয়োজনীয়তা) ওভাররাইড করার কোনও উপায় সরবরাহ করে বলে মনে হচ্ছে না । মো। প্রটেক্টেড এবং মক স্টাবের সাথে একই রকম ধারণা রয়েছে তবে তারা এই দৃশ্যের জন্য কোনও প্রস্তাব দেয় বলে মনে হয় না। আমি কি কিছু হারিয়ে যাচ্ছি বা আমার কি এটি অন্যভাবে চলতে হবে?

এখানে একটি তুচ্ছ উদাহরণ যা সাধারণ "অ-ওভারডেবল সদস্যের উপর অবৈধ প্রত্যাশা" দিয়ে ব্যর্থ হয় । এটি কোনও এক্সটেনশন পদ্ধতির উপহাস করার প্রয়োজনের একটি খারাপ উদাহরণ, তবে এটি করা উচিত।

public class SomeType {
    int Id { get; set; }
}

var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
        .Returns(new SomeType { Id = 5 });

যে কোনও টাইপমক জাঙ্কিজের ক্ষেত্রে এটির পরিবর্তে আমি আইসোলেটর ব্যবহার করার পরামর্শ দিতে পারি: আমি এই প্রচেষ্টাটির প্রশংসা করি যেহেতু দেখে মনে হচ্ছে যে টাইপমক কাজটি চোখের পাতানো এবং সংক্রামিত কাজ করতে পারে তবে আমাদের বাজেট খুব শীঘ্রই আর বাড়ছে না।


4
এখানে একটি সদৃশ পাওয়া যাবে: stackoverflow.com/questions/2295960/…
অলিভার

6
এই প্রশ্নটি তার চেয়ে পুরো বছর পুরনো। যদি সেখানে সদৃশ হয়, এটি অন্যভাবে যায়।
পৃষ্ঠপোষক

4
2019 সালে এখনও উপযুক্ত সমাধান নেই!
তানভীর আর্জেল

4
@ তানভীরআরজেল প্রকৃতপক্ষে, বহু বছর থেকে আপনি জাস্টমককে ম্যাক এক্সটেনশন পদ্ধতিগুলি ব্যবহার করতে পারেন । এবং অন্য যে কোনও পদ্ধতিকে উপহাস করার মতোই সহজ। এখানে ডকুমেন্টেশনের লিঙ্কটি রয়েছে: সম্প্রসারণের পদ্ধতিগুলি উপহাস করা
মিহাইল ভ্লাদভ

উত্তর:


71

এক্সটেনশন পদ্ধতি ছদ্মবেশে কেবল স্থির পদ্ধতি methods মক বা রাইনমকসের মতো মজাদার ফ্রেমওয়ার্কগুলি কেবলমাত্র বস্তুর মক উদাহরণ তৈরি করতে পারে, এর অর্থ স্থির পদ্ধতিগুলি উপহাস করা সম্ভব নয়।


69
@ মেন্ডল্ট..তখন কীভাবে একটি ইউনিট অভ্যন্তরীণভাবে একটি বর্ধিত পদ্ধতি রয়েছে এমন কোনও পদ্ধতি পরীক্ষা করবে? সম্ভাব্য বিকল্পগুলি কী কী?
সাই অবিনাশ

4
@ আলেকজান্দার আমারও একই প্রশ্ন ছিল এবং তারপরে এটি চমত্কারভাবে উত্তর দিয়েছে: agooddayforsজ্ঞ.blogspot.com/2017/08/… -এটি দেখুন, এটি জীবন রক্ষাকারী !
21

31

আপনি যদি এক্সটেনশন পদ্ধতিগুলির কোডটি পরিবর্তন করতে পারেন তবে আপনি পরীক্ষায় সক্ষম হতে এই জাতীয় কোডটি এটি করতে পারেন:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

public static class MyExtensions
{
    public static IMyImplementation Implementation = new MyImplementation();

    public static string MyMethod(this object obj)
    {
        return Implementation.MyMethod(obj);
    }
}

public interface IMyImplementation
{
    string MyMethod(object obj);
}

public class MyImplementation : IMyImplementation
{
    public string MyMethod(object obj)
    {
        return "Hello World!";
    }
}

সুতরাং এক্সটেনশন পদ্ধতিগুলি বাস্তবায়ন ইন্টারফেসের চারপাশে কেবল একটি মোড়ক।

(আপনি সিনট্যাকটিক চিনির সাজানোর মতো এক্সটেনশন পদ্ধতি ছাড়াই কেবল প্রয়োগকারী ক্লাস ব্যবহার করতে পারেন))

এবং আপনি বাস্তবায়ন ইন্টারফেসটিকে উপহাস করতে পারেন এবং এটি এক্সটেনশন শ্রেণীর জন্য বাস্তবায়ন হিসাবে সেট করতে পারেন।

public class MyClassUsingExtensions
{
    public string ReturnStringForObject(object obj)
    {
        return obj.MyMethod();
    }
}

[TestClass]
public class MyTests
{
    [TestMethod]
    public void MyTest()
    {
        // Given:
        //-------
        var mockMyImplementation = new Mock<IMyImplementation>();

        MyExtensions.Implementation = mockMyImplementation.Object;

        var myClassUsingExtensions = new MyClassUsingExtensions();

        // When:
        //-------
        var myObject = new Object();
        myClassUsingExtensions.ReturnStringForObject(myObject);

        //Then:
        //-------
        // This would fail because you cannot test for the extension method
        //mockMyImplementation.Verify(m => m.MyMethod());

        // This is success because you test for the mocked implementation interface
        mockMyImplementation.Verify(m => m.MyMethod(myObject));
    }
}

16

আমি জানি এই প্রশ্নটি প্রায় এক বছর ধরে সক্রিয় ছিল না তবে মাইক্রোসফ্ট একে একে মোলস বলে ঠিকঠাক পরিচালনা করার জন্য একটি কাঠামো প্রকাশ করেছিল ।

এখানে কয়েকটি টিউটোরিয়ালও রয়েছে:

  • ডাইমকাস্ট.নাট
  • নিকোলাই টিলম্যানের টিউটোরিয়াল


  • 15

    আমি যে এক্সটেনশন পদ্ধতিগুলি উপহাস করার জন্য প্রয়োজন তার জন্য একটি মোড়কের ক্লাস তৈরি করেছি।

    public static class MyExtensions
    {
        public static string MyExtension<T>(this T obj)
        {
            return "Hello World!";
        }
    }
    
    public interface IExtensionMethodsWrapper
    {
        string MyExtension<T>(T myObj);
    }
    
    public class ExtensionMethodsWrapper : IExtensionMethodsWrapper
    {
        public string MyExtension<T>(T myObj)
        {
            return myObj.MyExtension();
        }
    }
    

    তারপরে আপনি নিজের আইওসি পাত্রে আপনার পরীক্ষাগুলিতে এবং কোডে মোড়কের পদ্ধতিগুলি উপহাস করতে পারেন।


    এটি এমন এক কার্যকারিতা যেখানে আপনি নিজের কোডে আর এক্সটেনশন পদ্ধতি সিনট্যাক্স ব্যবহার করতে পারবেন না। আপনি যখন এক্সটেনশন পদ্ধতিগুলির ক্লাস পরিবর্তন করতে পারবেন না তবে এটি সহায়তা করে।
    informatorius

    @ ইনফরম্টোরিয়াস এর অর্থ কী? আপনার কোডে আপনি মাই এক্সটেনশন ক্লাস থেকে মাই এক্সটেনশন () ব্যবহার করেন। আপনার পরীক্ষাগুলিতে, আপনি পরামিতি সরবরাহকারী এক্সটেনশনমিথড্র্যাপার () শ্রেণি থেকে মাই এক্সটেনশন () ব্যবহার করেন।
    র‌্যাথনিনিসেন

    যদি পরীক্ষার অধীনে আমার ক্লাসটি মাই এক্সটেনশনগুলি থেকে মাই এক্সটেনশন () ব্যবহার করে তবে আমি মাই এক্সটেনশনগুলিকে উপহাস করতে পারি না। সুতরাং পরীক্ষার অধীনে থাকা শ্রেণিগুলিকে অবশ্যই আইসেক্সটেনশন মেঠড্র্যাপার ব্যবহার করতে হবে যাতে এটি উপহাস করা যায়। কিন্তু তারপরে পরীক্ষার অধীন শ্রেণিগুলি আর এক্সটেনশন পদ্ধতির সিনট্যাক্স ব্যবহার করতে পারে না।
    informatorius

    4
    ওপি এর পুরো বিষয়টি। এটি তার পক্ষে একান্ত কার্যনির্বাহী।
    র‌্যাথনিসিসন

    4

    এক্সটেনশন পদ্ধতির জন্য আমি সাধারণত নিম্নলিখিত পদ্ধতিটি ব্যবহার করি:

    public static class MyExtensions
    {
        public static Func<int,int, int> _doSumm = (x, y) => x + y;
    
        public static int Summ(this int x, int y)
        {
            return _doSumm(x, y);
        }
    }
    

    এটি _doSumm মোটামুটি সহজভাবে ইনজেকশনের অনুমতি দেয়।


    4
    আমি কেবল এটি চেষ্টা করেছিলাম কিন্তু পিতামাতার বিদ্রূপ করা বিষয়টিকে পাশ করার সময় সমস্যাগুলি রয়েছে যখন এটি অন্য কোনও বিধানসভায় থাকা অন্য কোনও পদ্ধতিতে পাস করার সময় এই এক্সটেনশনটির জন্য। সেক্ষেত্রে এমনকি এই কৌশলটির সাথেও যখন অন্য সমাবেশে পদ্ধতিটি আহ্বান করা হয় তখন মূল প্রসারণটি বাছাই করা হয়, একটি স্কোপিং ইস্যুতে সাজানো। আমি যদি ইউনিট টেস্ট প্রকল্পে সরাসরি কল করি তবে এটি ঠিক আছে, তবে আপনি যখন অন্য কোডটি পরীক্ষা করছেন যখন এক্সটেনশন পদ্ধতিটি কল করে এটি কেবল সহায়তা করে না।
    স্টিফেন ইয়র্ক

    @ স্টেফেন কীভাবে এড়ানো যায় তা নিশ্চিত নয়। আমার কখনও এই ধরণের স্কোপিং ইস্যু হয়নি
    ডমিগো

    0

    আপনি যে সর্বোত্তম কাজটি করতে পারেন তা হ'ল ধরণের এক্সটেনশন পদ্ধতি রয়েছে এমনটির জন্য একটি কাস্টম বাস্তবায়ন সরবরাহ করা যেমন:

    [Fact]
    public class Tests
    {
        public void ShouldRunOk()
        {
            var service = new MyService(new FakeWebHostEnvironment());
    
            // Service.DoStuff() internally calls the SomeExtensionFunction() on IWebHostEnvironment
            // Here it works just fine as we provide a custom implementation of that interface
            service.DoStuff().Should().NotBeNull();
        }
    }
    
    public class FakeWebHostEnvironment : IWebHostEnvironment
    {
        /* IWebHostEnvironment implementation */
    
        public bool SomeExtensionFunction()
        {
            return false;
        }
    }
    
    আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
    Licensed under cc by-sa 3.0 with attribution required.