কীভাবে কনফিগারেশন ম্যানেজ.অর অ্যাপ্লিকেশনগুলিকে moq সহ উপহাস করবেন


123

আমি কোডের এই বিন্দুতে আটকে আছি যে আমি কীভাবে উপহাস করতে জানি না:

ConfigurationManager.AppSettings["User"];

আমি ব্যবহার করছি ConfigurationManager উপহাস করতে হবে, কিন্তু আমি একটি খেই না, MOQ

কেউ আমাকে টিপস দিতে পারেন? ধন্যবাদ!

উত্তর:


103

আমি বিশ্বাস করি এটির একটি মানক পদ্ধতি হল কনফিগারেশন ম্যানেজারটি মোড়ানোর জন্য একটি ফ্যাকাস প্যাটার্ন ব্যবহার করা এবং তারপরে আপনার কিছুটা looseিলে .ালাভাবে জুড়ে থাকে যা আপনার নিয়ন্ত্রণে রয়েছে have

সুতরাং আপনি কনফিগারেশন ম্যানেজার মোড়ানো হবে। কিছুটা এইরকম:

public class Configuration: IConfiguration
{
    public User
    {
        get
        { 
            return ConfigurationManager.AppSettings["User"];
        }
    }
}

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


6
এটি ধারণাগতভাবে আমিও করছি। তবে, আমি ক্যাসল অভিধানআডাপ্টার ( ক্যাসল কোর এর অংশ ) ব্যবহার করি যা ফ্লাইতে ইন্টারফেসের বাস্তবায়ন উত্পন্ন করে। আমি এটি সম্পর্কে কিছুক্ষণ আগে লিখেছি : blog.andreloker.de/post/2008/09/05/… (আমি ক্যাসল ডিকশনারি অ্যাডাপ্টারটি কীভাবে ব্যবহার করি তা দেখতে "একটি সমাধান" এ স্ক্রোল করুন)
আন্দ্রে লোকার

এটি নিফটি এবং এটি একটি ভাল নিবন্ধ। আমি ভবিষ্যতের জন্য এটি মাথায় রাখতে হবে।
জোশুয়া এনফিল্ড

আমি আপনার শুদ্ধিকরণ এবং ব্যাখ্যার উপর নির্ভর করেও যুক্ত করতে পারি - এটির পরিবর্তে বা ডেলিগেট প্রক্সি বা অ্যাডাপ্টারও বলা যেতে পারে।
জোশুয়া এনফিল্ড

3
উপরের দিক থেকে এটি কেবল মোককে "সাধারণ" হিসাবে ব্যবহার করছে। অনির্ধারিত, তবে এর মতো কিছু: var configurationMock = new Mock<IConfiguration>();এবং সেটআপের জন্য:configurationMock.SetupGet(s => s.User).Returns("This is what the user property returns!");
জোশুয়া এনফিল্ড

এই দৃশ্যটি ব্যবহার করা হয় যখন কোনও স্তরটি আইকনফিগারেশনের উপর নির্ভর করে এবং আপনাকে আইকনফিগারেশনকে উপহাস করতে হবে, তবে আপনি কীভাবে আইকনফাইগ্রেশন বাস্তবায়ন পরীক্ষা করবেন? আপনি যদি ইউনিট টেস্ট কনফিগারেশন ম্যানেজার.অ্যাপসেটেটিংস "" ব্যবহারকারী "] এ কল করেন তবে এটি ইউনিটটি পরীক্ষা করে না, তবে কনফিগারেশন ফাইল থেকে কোন মানগুলি আনা হয়েছে তা পরীক্ষা করে দেখায় যা কোন ইউনিট পরীক্ষা নয়। যদি আপনার বাস্তবায়নটি পরীক্ষা করতে হয় তবে দেখুন @ zpbappi.com/testing-codes-with-configrationmanage-appsettings
nkalfov

173

আমি AspnetMvc4 ব্যবহার করছি। এক মুহুর্ত আগে লিখেছিলাম

ConfigurationManager.AppSettings["mykey"] = "myvalue";

আমার পরীক্ষার পদ্ধতিতে এবং এটি পুরোপুরি কার্যকর হয়েছিল।

ব্যাখ্যা: পরীক্ষার পদ্ধতিটি অ্যাপ্লিকেশন সেটিংস, সাধারণত একটি web.configবা থেকে নেওয়া সংক্রান্ত প্রসঙ্গে চলে myapp.configConfigurationsManagerএই অ্যাপ্লিকেশন-গ্লোবাল অবজেক্টে পৌঁছাতে এবং এটিকে পরিচালনা করতে পারে ulate

যদিও: আপনার যদি সমান্তরালে টেস্ট রানার চলমান পরীক্ষা থাকে তবে এটি ভাল ধারণা নয়।


8
সমস্যাটি সমাধানের এটি সত্যই চতুর এবং সহজ উপায়! সরলতার জন্য কুডোস!
নাভপ

1
বেশিরভাগ ক্ষেত্রে বিমূর্ততা তৈরির চেয়ে অনেক বেশি সহজ
মাইকেল ক্লার্ক

2
এটাই???? আমি কীভাবে এই নির্দিষ্ট সিল করা ক্লাসটি পরীক্ষা করতে পারি তা সম্পর্কে আমার মস্তিষ্ককে পরীক্ষা করে দেখছিলাম তেজতা সরলতায় রয়েছে।
পাইটর কুলা

5
ConfigurationManager.AppSettingsএটি একটি NameValueCollectionযা থ্রেড-নিরাপদ নয়, সুতরাং সমান্তরাল পরীক্ষাগুলি সঠিক সিঙ্ক্রোনাইজেশন ছাড়াই এটি ব্যবহার করা যাইহোক ভাল ধারণা নয়। অন্যথায় আপনি কেবল ConfigurationManager.AppSettings.Clear()আপনার TestInitialize/ সিটিতে কল করতে পারেন এবং আপনি সোনার।
ওহাদ স্নাইডার

1
সহজ এবং সংক্ষিপ্ত। এখন পর্যন্ত সেরা উত্তর!
znn

21

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


7
যদি পরীক্ষার অধীনে কোডটির আচরণ কোনও কনফিগারেশনের মানের উপর নির্ভর করে পরিবর্তিত হয় তবে এটি সরাসরি অ্যাপসেটেটিংয়ের উপর নির্ভর না করে তবে এটি পরীক্ষা করা অবশ্যই সহজ।
আন্দ্রে লোকার

2
এটি খারাপ অনুশীলন কারণ আপনি কখনই অন্যান্য সম্ভাব্য সেটিংস পরীক্ষা করছেন না। জোশুয়া এনফিল্ডের উত্তর পরীক্ষার জন্য দুর্দান্ত।
এমকাজ

4
অন্যরা এই উত্তরের বিরুদ্ধে থাকলেও আমি বলব যে তাদের অবস্থানটি কিছুটা সাধারণীকরণযোগ্য। এটি কিছু পরিস্থিতিতে একটি খুব বৈধ উত্তর এবং এটি আপনার প্রয়োজনের উপর নির্ভর করে। উদাহরণস্বরূপ, আসুন আমি বলি যে আমার কাছে 4 টি আলাদা ক্লাস্টার রয়েছে, প্রত্যেকটির আলাদা আলাদা ইউআরএল রয়েছে। এই 4 টি ক্লাস্টারগুলি Web.configপ্রকল্পের আওতাধীন থেকে রানটাইমের সময় টানা হয় are পরীক্ষার সময়, এর থেকে কিছু সুপরিচিত মানগুলি টানানো app.configখুব কার্যকর। ইউনিট টেস্টে কেবল "ক্লাস্টার 1" বলার সময় শর্তগুলি নিশ্চিত করা দরকার; এক্ষেত্রে কেবল 4 টি আলাদা ক্লাস্টার রয়েছে।
মাইক পেরেনউড

14

আপনি AppSettingsকাস্টম NameValueCollectionঅবজেক্টে পরিবর্তন করতে শিম ব্যবহার করতে পারেন । আপনি কীভাবে এটি অর্জন করতে পারেন তার একটি উদাহরণ এখানে দেওয়া হয়েছে:

[TestMethod]
public void TestSomething()
{
    using(ShimsContext.Create()) {
        const string key = "key";
        const string value = "value";
        ShimConfigurationManager.AppSettingsGet = () =>
        {
            NameValueCollection nameValueCollection = new NameValueCollection();
            nameValueCollection.Add(key, value);
            return nameValueCollection;
        };

        ///
        // Test code here.
        ///

        // Validation code goes here.        
    }
}

মাইক্রোসফ্ট ফেকসের সাথে টেস্টের অধীনে আইসোলেটিং কোডে আপনি শিম এবং জাল সম্পর্কে আরও পড়তে পারেন । আশাকরি এটা সাহায্য করবে.


6
লেখক এমএস জালিয়াতি সম্পর্কে নয়, মোখ দিয়ে কীভাবে করবেন তা জিজ্ঞাসা করছেন।
জেপিসিএফ

6
এবং এটি কীভাবে আলাদা? এটি তার কোড থেকে ডেটা নির্ভরতা সরিয়ে বিদ্রূপ অর্জন করে। সি # জাল ব্যবহার একটি পদ্ধতি!
জোড়ায়ার

9

আপনি কি ঠাট্টা-বিদ্রূপ করার পরিবর্তে খড়খড়ি বিবেচনা করেছেন? AppSettingsসম্পত্তি একটি হল NameValueCollection:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        // Arrange
        var settings = new NameValueCollection {{"User", "Otuyh"}};
        var classUnderTest = new ClassUnderTest(settings);

        // Act
        classUnderTest.MethodUnderTest();

        // Assert something...
    }
}

public class ClassUnderTest
{
    private readonly NameValueCollection _settings;

    public ClassUnderTest(NameValueCollection settings)
    {
        _settings = settings;
    }

    public void MethodUnderTest()
    {
        // get the User from Settings
        string user = _settings["User"];

        // log
        Trace.TraceInformation("User = \"{0}\"", user);

        // do something else...
    }
}

সুবিধাগুলি একটি সহজ বাস্তবায়ন এবং সিস্টেমের উপর নির্ভরতা নেই on কনফিগারেশনের আপনার সত্যিকার প্রয়োজন না হওয়া পর্যন্ত।


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

2

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

উপহাসের পরিসংখ্যানগুলির জন্য, আমি মোলস নামে একটি সরঞ্জাম ব্যবহার করি যা বিনামূল্যে। অন্যান্য কাঠামো বিচ্ছিন্নকরণ সরঞ্জাম রয়েছে যেমন টাইপমক যা এটিও করতে পারে, যদিও আমি বিশ্বাস করি সেগুলি প্রদত্ত সরঞ্জাম are

যখন এটি স্ট্যাটিকস এবং টেস্টিংয়ের কথা আসে, তখন অন্য একটি বিকল্প হ'ল স্ট্যাটিক স্টেটটি নিজে তৈরি করা, যদিও এটি প্রায়শই সমস্যাযুক্ত হতে পারে (যেমন, আমি ভাবছিলাম এটি আপনার ক্ষেত্রে হবে)।

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


1

আমি মনে করি আপনার নিজের অ্যাপ.config সরবরাহকারীর লেখা একটি সহজ কাজ এবং অন্য যে কোনও কিছু থেকে বেশি কার্যকর। বিশেষত আপনার শিমস ইত্যাদি কোনও জাল এড়ানো উচিত কারণ আপনি এগুলি ব্যবহার করার সাথে সাথে সম্পাদনা এবং চালিয়ে যাওয়া আর কাজ করে না works

আমি যে সরবরাহকারী ব্যবহার করি তারা এর মতো দেখতে:

ডিফল্টরূপে তারা মানগুলি পায় App.configতবে ইউনিট পরীক্ষার জন্য আমি সমস্ত মানকে ওভাররাইড করতে এবং প্রতিটি পরীক্ষায় স্বাধীনভাবে ব্যবহার করতে পারি।

কোনও ইন্টারফেসের প্রয়োজন নেই বা বারবার এটি প্রয়োগ করা হবে। আমার কাছে একটি ইউটিলিটি রয়েছে এবং অনেকগুলি প্রকল্প এবং ইউনিট পরীক্ষায় এই ছোট সহায়কটি ব্যবহার করি।

public class AppConfigProvider
{
    public AppConfigProvider()
    {
        ConnectionStrings = new ConnectionStringsProvider();
        AppSettings = new AppSettingsProvider();
    }

    public ConnectionStringsProvider ConnectionStrings { get; private set; }

    public AppSettingsProvider AppSettings { get; private set; }
}

public class ConnectionStringsProvider
{
    private readonly Dictionary<string, string> _customValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    public string this[string key]
    {
        get
        {
            string customValue;
            if (_customValues.TryGetValue(key, out customValue))
            {
                return customValue;
            }

            var connectionStringSettings = ConfigurationManager.ConnectionStrings[key];
            return connectionStringSettings == null ? null : connectionStringSettings.ConnectionString;
        }
    }

    public Dictionary<string, string> CustomValues { get { return _customValues; } }
}

public class AppSettingsProvider
{
    private readonly Dictionary<string, string> _customValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    public string this[string key]
    {
        get
        {
            string customValue;
            return _customValues.TryGetValue(key, out customValue) ? customValue : ConfigurationManager.AppSettings[key];
        }
    }

    public Dictionary<string, string> CustomValues { get { return _customValues; } }
}

1

আপনার যা প্রয়োজন তা ঠিক করার বিষয়ে কীভাবে? কারণ, আমি ঠাট্টা করতে চাই না। নেট, আমি ...?

System.Configuration.ConfigurationManager.AppSettings["myKey"] = "myVal";

অ্যাপ্লিকেশনটি কেবল আপনার কী চায় তা কেবল এটিই দেখেছে তা নিশ্চিত করার জন্য আপনার সম্ভবত অ্যাপসেটিংগুলি আগেই পরিষ্কার করা উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.