আমি একটি শ্রেণিবদ্ধ গ্রন্থাগার তৈরি করছি যাতে কিছু সরকারী ও ব্যক্তিগত পদ্ধতি থাকবে। আমি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করতে সক্ষম হতে চাই (বেশিরভাগ বিকাশের সময়, তবে এটি ভবিষ্যতের রিফ্যাক্টরিংয়ের জন্যও কার্যকর হতে পারে)।
এটি করার সঠিক উপায় কী?
আমি একটি শ্রেণিবদ্ধ গ্রন্থাগার তৈরি করছি যাতে কিছু সরকারী ও ব্যক্তিগত পদ্ধতি থাকবে। আমি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করতে সক্ষম হতে চাই (বেশিরভাগ বিকাশের সময়, তবে এটি ভবিষ্যতের রিফ্যাক্টরিংয়ের জন্যও কার্যকর হতে পারে)।
এটি করার সঠিক উপায় কী?
উত্তর:
আপনি যদি নেট ব্যবহার করে থাকেন তবে আপনার ইন্টারনালভিসিবলটোঅ্যাট্রিবিউট ব্যবহার করা উচিত ।
#if DEBUG
প্রায় InternalsVisibleTo
নয় রিলিজ কোড প্রযোজ্য করা অ্যাট্রিবিউট?
#if RELEASE_TEST
চারপাশের InternalsVisibleTo
মতো কিছু ব্যবহার করা এবং আপনার প্রকাশের বিল্ড কনফিগারেশনের একটি অনুলিপি তৈরি করা যা সংজ্ঞায়িত করে RELEASE_TEST
। আপনি আপনার রিলিজ কোডটি অনুকূলিতকরণের সাথে পরীক্ষা করতে পারেন তবে আপনি যখন মুক্তির জন্য তৈরি করবেন তখন আপনার পরীক্ষাগুলি বাদ দেওয়া হবে।
আপনি যদি কোনও ব্যক্তিগত পদ্ধতি পরীক্ষা করতে চান তবে কিছু ভুল হতে পারে। ইউনিট টেস্টগুলি (সাধারণত কথা বলা) বোঝায় কোনও শ্রেণীর ইন্টারফেস পরীক্ষা করা, যার অর্থ জনসাধারণের (এবং সুরক্ষিত) পদ্ধতিগুলি। আপনি অবশ্যই এর সমাধান "হ্যাক" করতে পারেন (এমনকি পদ্ধতিগুলি জনসাধারণের দ্বারা প্রকাশ করা হলেও) তবে আপনি এটি বিবেচনা করতেও পারেন:
এটি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করার জন্য দরকারী নাও হতে পারে। তবে আমি মাঝে মাঝে পরীক্ষার পদ্ধতিগুলি থেকে ব্যক্তিগত পদ্ধতিগুলি কল করতে চাই। পরীক্ষার ডেটা তৈরির জন্য কোড নকল রোধ করার জন্য বেশিরভাগ সময় ...
মাইক্রোসফ্ট এর জন্য দুটি প্রক্রিয়া সরবরাহ করে:
Accessors
যাইহোক, মূল শ্রেণীর ইন্টারফেসের পরিবর্তনের ক্ষেত্রে মেকানিজমটি কখনও কখনও কিছুটা অক্ষম হয়। সুতরাং, বেশিরভাগ সময় আমি এটি ব্যবহার করা এড়িয়ে চলি।
প্রাইভেটঅবজেক্ট ক্লাসের অন্য উপায়টি হ'ল মাইক্রোসফ্ট.ভিজুয়াল স্টুডিও.স্টেস্টুলস.উনিটটেষ্টিং.প্রাইভেটঅজেক্ট
// Wrap an already existing instance
PrivateObject accessor = new PrivateObject( objectInstanceToBeWrapped );
// Retrieve a private field
MyReturnType accessiblePrivateField = (MyReturnType) accessor.GetField( "privateFieldName" );
// Call a private method
accessor.Invoke( "PrivateMethodName", new Object[] {/* ... */} );
"আপনার কেবলমাত্র বাহ্যিক ইন্টারফেসটি পরীক্ষা করতে আগ্রহী হওয়া উচিত" দর্শনের সাথে আমি একমত নই। এটি কিছুটা বলার মতো যে একটি গাড়ি মেরামতের দোকানে কেবল চাকাগুলি চালু আছে কিনা তা পরীক্ষা করতে হবে। হ্যাঁ, শেষ পর্যন্ত আমি বাহ্যিক আচরণে আগ্রহী কিন্তু আমি নিজের, ব্যক্তিগত, অভ্যন্তরীণ পরীক্ষাগুলি আরও কিছুটা নির্দিষ্ট এবং বিন্দুতে পছন্দ করি। হ্যাঁ, আমি যদি রিফ্যাক্টর করি তবে আমাকে কয়েকটি পরীক্ষার পরিবর্তন করতে হতে পারে, তবে এটি যদি একটি বিশাল চুল্লী না হয় তবে কেবলমাত্র কয়েকটি পরিবর্তন করতে হবে এবং অন্যান্য (অপরিবর্তিত) অভ্যন্তরীণ পরীক্ষাগুলি এখনও কাজ করছে তা একটি দুর্দান্ত সূচক যে রিফ্যাক্টরিং সফল হয়েছে।
আপনি কেবলমাত্র পাবলিক ইন্টারফেস ব্যবহার করে সমস্ত অভ্যন্তরীণ কেসগুলি coverেকে দেওয়ার চেষ্টা করতে পারেন এবং তাত্ত্বিকভাবে প্রতিটি অভ্যন্তরীণ পদ্ধতির (বা কমপক্ষে প্রতিটি যেটি গুরুত্বপূর্ণ) পুরোপুরি পাবলিক ইন্টারফেস ব্যবহার করে পরীক্ষা করা সম্ভব তবে অর্জনের জন্য আপনাকে নিজের মাথার উপর দাঁড়িয়ে থাকতে হতে পারে এটি এবং সর্বজনীন ইন্টারফেসের মাধ্যমে পরীক্ষার কেসগুলির মধ্যে সংযোগ স্থাপন করা যেতে পারে এবং তারা যে সমাধানের জন্য পরীক্ষার জন্য ডিজাইন করেছেন তার অভ্যন্তরীণ অংশটি নির্ধারণ করা কঠিন বা অসম্ভব হতে পারে। স্বতন্ত্র, পৃথক পরীক্ষাগুলি যা গ্যারান্টি দেয় যে অভ্যন্তরীণ যন্ত্রপাতি সঠিকভাবে কাজ করছে সেগুলি রিফ্যাক্টরিংয়ের সাথে ঘটে আসা ছোটখাটো পরীক্ষার পরিবর্তনগুলির পক্ষে ভাল। কমপক্ষে আমার অভিজ্ঞতা হয়েছে। আপনাকে যদি প্রতিটি রিফ্যাক্টরিংয়ের জন্য আপনার পরীক্ষাগুলিতে বিশাল পরিবর্তন করতে হয়, তবে সম্ভবত এটির কোনও অর্থ হয় না, তবে সেই ক্ষেত্রে সম্ভবত আপনার নকশাটি পুরোপুরি পুনর্বিবেচনা করা উচিত।
FooService
কি আছে যে X
, সব আপনার পছন্দের উচিত যে এটা সত্যিই কাজ করে হয় X
যখন অনুরোধ করা হয়েছে। এটি কীভাবে করে তা বিবেচ্য নয়। যদি ইন্টারফেসের মাধ্যমে শ্রেণিতে সমস্যাগুলি উপলব্ধিযোগ্য না (অসম্ভব) তবে এটি এখনও একটি বৈধ FooService
। এটা একটা সমস্যা যে যদি হয় ইন্টারফেসের মাধ্যমে দৃশ্যমান, পাবলিক সদস্যদের উপর একটি পরীক্ষা এটি সনাক্ত করা উচিত নয়। পুরো বিষয়টিটি এমন হওয়া উচিত যে যতক্ষণ চাকাটি সঠিকভাবে ঘুরবে ততক্ষণ এটি চাকা হিসাবে ব্যবহার করা যেতে পারে।
PrivMethod
, কোন পরীক্ষা PubMethod
যার উপর কলগুলি PrivMethod
তা প্রকাশ করতে পারে? যখন আপনি আপনার পরিবর্তন কি হবে SimpleSmtpService
একটি করতে GmailService
? হঠাৎ আপনার সমস্ত ব্যক্তিগত পরীক্ষাগুলি কোডের দিকে ইঙ্গিত করছে যা অস্তিত্বহীন বা সম্ভবত অন্যরকমভাবে কাজ করে এবং ব্যর্থ হয়, যদিও অ্যাপ্লিকেশনটি নকশা অনুসারে পুরোপুরি কাজ করতে পারে। যদি এমন জটিল প্রক্রিয়াজাতকরণ থাকে যা ইমেল প্রেরকদের উভয়ের জন্যই প্রযোজ্য, সম্ভবত এটি এমন কোনও হওয়া উচিত EmailProcessor
যা উভয়ই ব্যবহার করতে পারবেন এবং পৃথকভাবে পরীক্ষা করতে পারবেন?
বিরল ক্ষেত্রে আমি ব্যক্তিগত ফাংশনগুলি পরীক্ষা করতে চেয়েছি, আমি সাধারণত সেগুলি পরিবর্তে সুরক্ষিত রাখতে সংশোধন করেছি এবং আমি একটি পাবলিক রেপার ফাংশন সহ একটি সাবক্লাস লিখেছি।
শ্রেণী:
...
protected void APrivateFunction()
{
...
}
...
পরীক্ষার জন্য সাবক্লাস:
...
[Test]
public void TestAPrivateFunction()
{
APrivateFunction();
//or whatever testing code you want here
}
...
আমি মনে করি আরও একটি মৌলিক প্রশ্ন জিজ্ঞাসা করা উচিত তা হল আপনি কেন প্রথমে ব্যক্তিগত পদ্ধতিটি পরীক্ষা করার চেষ্টা করছেন। এটি এমন একটি কোডের গন্ধ যা আপনি সেই শ্রেণীর পাবলিক ইন্টারফেসের মাধ্যমে ব্যক্তিগত পদ্ধতিটি পরীক্ষা করার চেষ্টা করছেন তবে সেই পদ্ধতিটি বাস্তবায়নের বিশদ হিসাবে কোনও কারণে এটি ব্যক্তিগত। একজনকে কেবল জনসাধারণের ইন্টারফেসের আচরণের সাথে সম্পর্কিত হওয়া উচিত নয় কীভাবে এটি কভারগুলির আওতায় কার্যকর করা হয়।
আমি যদি সাধারণ পদ্ধতিতে ব্যবহার করে ব্যক্তিগত পদ্ধতির আচরণটি পরীক্ষা করতে চাই, তবে আমি এর কোডটি অন্য শ্রেণিতে বের করতে পারি (প্যাকেজ স্তরের দৃশ্যমানতার সাথে এটি নিশ্চিত করে এটি কোনও পাবলিক এপিআইয়ের অংশ নয়)। এরপরে আমি এর আচরণটি বিচ্ছিন্নভাবে পরীক্ষা করতে পারি।
রিফ্যাক্টরিংয়ের পণ্যটির অর্থ হ'ল বেসরকারী পদ্ধতিটি এখন একটি পৃথক শ্রেণি যা মূল শ্রেণীর সহযোগী হয়ে উঠেছে। এর নিজস্ব ইউনিট পরীক্ষার মাধ্যমে এর আচরণটি ভালভাবে বোঝা যাবে।
আমি যখন আসল ক্লাসটি পরীক্ষা করার চেষ্টা করি তখন আমি তার আচরণকে বিদ্রূপ করতে পারি, যাতে আমি তখন পাবলিক ইন্টারফেসের সংযুক্ত বিস্ফোরণ এবং তার সমস্ত ব্যক্তিগত পদ্ধতির আচরণের পরীক্ষা না করে class শ্রেণীর পাবলিক ইন্টারফেসের আচরণ এবং পরীক্ষার দিকে মনোনিবেশ করতে পারি ।
আমি গাড়ি চালানোর সাথে এটি সাদৃশ্য দেখছি। আমি যখন গাড়ি চালনা করি তখন আমি বোনট দিয়ে গাড়ি চালাতাম না তাই দেখতে পাচ্ছি যে ইঞ্জিনটি কাজ করছে। আমি গাড়িটি যে ইন্টারফেসটি সরবরাহ করে তার উপর নির্ভর করি, যেমন ইঞ্জিনটি কাজ করছে তা জানার জন্য রেভ কাউন্টার এবং স্পিডোমিটার। আমি যখন গ্যাসের প্যাডেল টিপতাম তখন গাড়ীটি আসলে চলাচল করে। যদি আমি ইঞ্জিনটি পরীক্ষা করতে চাই তবে আমি বিচ্ছিন্নভাবে এটিতে চেক করতে পারি। : ডি
অবশ্যই আপনার যদি কোনও উত্তরাধিকারের আবেদন থাকে তবে ব্যক্তিগত পদ্ধতিগুলির পরীক্ষা সরাসরি শেষ অবলম্বন হতে পারে তবে আমি পছন্দ করি যে উত্তরাধিকার কোডটি আরও ভাল পরীক্ষার সক্ষম করার জন্য রিফেক্টরেড হয়। মাইকেল ফেদারস খুব এই বিষয়ে একটি দুর্দান্ত বই লিখেছেন। http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052
ব্যক্তিগত ধরণের, অভ্যন্তরীণ এবং প্রাইভেট সদস্যরা কোনও কারণে এই কারণেই থাকে এবং প্রায়শই আপনি সরাসরি তাদের সাথে ঝামেলা করতে চান না। এবং যদি আপনি এটি করেন তবে সম্ভাবনা হ'ল আপনি পরে ভেঙে যাবেন, কারণ এই সম্মেলনগুলি তৈরি করা ছেলেরা ব্যক্তিগত / অভ্যন্তরীণ বাস্তবায়ন যেমন রাখবে তার কোনও গ্যারান্টি নেই।
তবে, কখনও কখনও সংকলিত বা তৃতীয় পক্ষের অ্যাসেমব্লির কয়েকটি হ্যাক / অন্বেষণ করার সময়, আমি নিজেই একটি প্রাইভেট ক্লাস বা একটি ব্যক্তিগত বা অভ্যন্তরীণ কনস্ট্রাক্টর সহ একটি শ্রেণীর সূচনা করার ইচ্ছা শেষ করেছি। বা, কখনও কখনও, প্রাক-সংকলিত উত্তরাধিকার লাইব্রেরিগুলি যখন আমি পরিবর্তন করতে পারি না তার সাথে ডিল করার সময় - আমি একটি ব্যক্তিগত পদ্ধতির বিপরীতে কিছু পরীক্ষা লিখি।
এইভাবে অ্যাক্সেসপ্রাইভেট্র্যাপারের জন্ম হয় - http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html - এটি একটি দ্রুত মোড়কের ক্লাস যা C # 4.0 গতিশীল বৈশিষ্ট্য এবং প্রতিবিম্ব ব্যবহার করে কাজটিকে সহজ করে তুলবে।
আপনি অভ্যন্তরীণ / ব্যক্তিগত ধরণের পছন্দ তৈরি করতে পারেন
//Note that the wrapper is dynamic
dynamic wrapper = AccessPrivateWrapper.FromType
(typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");
//Access the private members
wrapper.PrivateMethodInPrivateClass();
ভাল আপনি দুটি পদ্ধতিতে ব্যক্তিগত পদ্ধতি পরীক্ষা করতে পারেন
আপনি PrivateObject
শ্রেণীর উদাহরণ তৈরি করতে পারেন সিনট্যাক্সটি নিম্নরূপ
PrivateObject obj= new PrivateObject(PrivateClass);
//now with this obj you can call the private method of PrivateCalss.
obj.PrivateMethod("Parameters");
আপনি প্রতিবিম্ব ব্যবহার করতে পারেন।
PrivateClass obj = new PrivateClass(); // Class containing private obj
Type t = typeof(PrivateClass);
var x = t.InvokeMember("PrivateFunc",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Instance, null, obj, new object[] { 5 });
PrivateClass
প্রথমে একটি উদাহরণ ঘোষণা করতে হবে এবং এটি ব্যবহার করতে হবে। stackoverflow.com/questions/9122708/...
আমি ইন্টার্নালভিজিবলটোঅ্যাট্রিবিউট পদ্ধতিটিও ব্যবহার করেছি। এটিও উল্লেখ করার মতো যে, যদি আপনি এটি অর্জনের জন্য আপনার পূর্ববর্তী ব্যক্তিগত পদ্ধতিগুলি অভ্যন্তরীণ করে তুলতে অস্বস্তি বোধ করেন, তবে সম্ভবত সেগুলি যে কোনও উপায়ে সরাসরি ইউনিট পরীক্ষার বিষয় হওয়া উচিত নয়।
সর্বোপরি, আপনি নিজের শ্রেণীর আচরণটি নির্দিষ্ট প্রয়োগের পরিবর্তে পরীক্ষা করছেন - আপনি পূর্বের পরিবর্তন না করে আধুনিক পরিবর্তন করতে পারেন এবং আপনার পরীক্ষাগুলি এখনও পাস হওয়া উচিত।
এখানে 2 ধরণের ব্যক্তিগত পদ্ধতি রয়েছে। স্ট্যাটিক প্রাইভেট পদ্ধতি এবং নন স্ট্যাটিক ব্যক্তিগত পদ্ধতি (তাত্ক্ষণিক পদ্ধতি)। নিম্নলিখিত 2 টি নিবন্ধগুলিতে উদাহরণ সহ বেসরকারী পদ্ধতি পরীক্ষা করার পদ্ধতি সম্পর্কে ব্যাখ্যা করা হয়েছে।
এমএস টেস্টে নির্মিত একটি দুর্দান্ত বৈশিষ্ট্য রয়েছে যা ভিএসকোডজেনএ্যাকসেসরস নামে একটি ফাইল তৈরি করে প্রাইভেট সদস্য এবং পদ্ধতিগুলিকে প্রকল্পে উপলব্ধ করে তোলে in
[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class BaseAccessor
{
protected Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject m_privateObject;
protected BaseAccessor(object target, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
{
m_privateObject = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(target, type);
}
protected BaseAccessor(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
:
this(null, type)
{
}
internal virtual object Target
{
get
{
return m_privateObject.Target;
}
}
public override string ToString()
{
return this.Target.ToString();
}
public override bool Equals(object obj)
{
if (typeof(BaseAccessor).IsInstanceOfType(obj))
{
obj = ((BaseAccessor)(obj)).Target;
}
return this.Target.Equals(obj);
}
public override int GetHashCode()
{
return this.Target.GetHashCode();
}
}
বেসএ্যাক্সেসর থেকে প্রাপ্ত ক্লাসগুলির সাথে
যেমন
[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class SomeClassAccessor : BaseAccessor
{
protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::Namespace.SomeClass));
internal SomeClassAccessor(global::Namespace.Someclass target)
: base(target, m_privateType)
{
}
internal static string STATIC_STRING
{
get
{
string ret = ((string)(m_privateType.GetStaticField("STATIC_STRING")));
return ret;
}
set
{
m_privateType.SetStaticField("STATIC_STRING", value);
}
}
internal int memberVar {
get
{
int ret = ((int)(m_privateObject.GetField("memberVar")));
return ret;
}
set
{
m_privateObject.SetField("memberVar", value);
}
}
internal int PrivateMethodName(int paramName)
{
object[] args = new object[] {
paramName};
int ret = (int)(m_privateObject.Invoke("PrivateMethodName", new System.Type[] {
typeof(int)}, args)));
return ret;
}
কোডপ্রজেক্টে, একটি নিবন্ধ রয়েছে যা ব্যক্তিগত পদ্ধতি পরীক্ষা করার পক্ষে সংক্ষেপে সংক্ষেপে আলোচনা করে। এরপরে এটি ব্যক্তিগত পদ্ধতিতে অ্যাক্সেসের জন্য কিছু প্রতিবিম্ব কোড সরবরাহ করে (উপরের কোডটি মার্কাস সরবরাহ করে to
আপনি এখানে নিবন্ধ খুঁজে পেতে পারেন:
এগুলি ঘোষণা করুন internal
এবং তারপরে InternalsVisibleToAttribute
আপনার ইউনিট পরীক্ষা সমাবেশটি তাদের দেখার অনুমতি দেওয়ার জন্য ব্যবহার করুন।
আমি সংকলক নির্দেশাবলী ব্যবহার না করার ঝোঁক করি কারণ তারা জিনিসগুলিকে দ্রুত বিশৃঙ্খল করে। আপনার যদি সত্যই তাদের প্রয়োজন হয় তা হ্রাস করার একটি উপায় হ'ল এটিকে আংশিক শ্রেণিতে স্থাপন করা এবং উত্পাদনের সংস্করণ তৈরি করার সময় আপনার বিল্ডটি সেই .cs ফাইলটিকে উপেক্ষা করা উচিত।
আপনার কোডটির ব্যক্তিগত পদ্ধতিগুলি প্রথম স্থানে পরীক্ষা করা উচিত নয়। আপনার ক্লাসের সর্বজনীন জিনিসগুলি 'পাবলিক ইন্টারফেস' বা এপিআই পরীক্ষা করা উচিত। এপিআই হ'ল বাইরের কলকারীদের কাছে প্রকাশিত সমস্ত পাবলিক পদ্ধতি।
কারণটি হ'ল একবার আপনি যখন আপনার ক্লাসের ব্যক্তিগত পদ্ধতি এবং ইন্টার্নাল পরীক্ষা করতে শুরু করেন তখন আপনি আপনার ক্লাসের (ব্যক্তিগত জিনিসগুলি) প্রয়োগের সাথে সংযুক্ত হয়ে যাচ্ছেন। এর অর্থ হ'ল আপনি যখন নিজের প্রয়োগের বিশদটি পরিবর্তন করার সিদ্ধান্ত নেন তখন আপনাকে পরীক্ষাও পরিবর্তন করতে হবে।
আপনার এই কারণে ইন্টার্নালভিসিবলটোআউট্রিবিউট ব্যবহার করা এড়ানো উচিত।
এখানে ইয়ান কুপারের একটি দুর্দান্ত আলোচনা রয়েছে যা এই বিষয়টিকে কভার করে: ইয়ান কুপার: টিডিডি, এটি কোথায় ভুল হয়েছে?
কখনও কখনও, ব্যক্তিগত ঘোষণাগুলি পরীক্ষা করা ভাল হতে পারে। মৌলিকভাবে, একটি সংকলকটিতে কেবল একটি পাবলিক পদ্ধতি রয়েছে: সংকলন (স্ট্রিং আউটপুটফিলনাম, প্যারাম স্ট্রিং [] উত্সফিশননম)। আমি নিশ্চিত যে আপনি বুঝতে পেরেছেন যে প্রতিটি "লুকানো" ঘোষণাপত্র পরীক্ষা না করে এই জাতীয় পদ্ধতির পরীক্ষা করা কঠিন হবে!
এজন্য আমরা আরও সহজ পরীক্ষা করার জন্য ভিজ্যুয়াল টি #: তৈরি করেছি। এটি একটি ফ্রি। নেট প্রোগ্রামিং ভাষা (সি # ভি 2.0 সামঞ্জস্যপূর্ণ)।
আমরা '.-' অপারেটর যুক্ত করেছি। এটি ঠিক 'এর মতো আচরণ করে।' অপারেটর, আপনি ব্যতীত আপনার পরীক্ষিত প্রকল্পের কোনও পরিবর্তন না করেও পরীক্ষা থেকে কোনও গোপন ঘোষণাকে অ্যাক্সেস করতে পারেন।
আমাদের ওয়েব সাইটে কটাক্ষপাত: ডাউনলোড এটা বিনামূল্যে জন্য ।
আমি অবাক হয়েছি এখনও কেউ এ কথা বলেনি, তবে আমি নিযুক্ত একটি সমাধান হ'ল ক্লাসের অভ্যন্তরে একটি স্ট্যাটিক পদ্ধতি তৈরি করা যা নিজেই পরীক্ষা করে। এটি আপনাকে পরীক্ষা করার জন্য সরকারী এবং ব্যক্তিগত সমস্ত কিছুতে অ্যাক্সেস দেয়।
তদতিরিক্ত, একটি স্ক্রিপ্টিং ভাষায় (পাইওথন, রুবি এবং পিএইচপি এর মতো ওও সক্ষমতার সাথে), রান করার সময় আপনি ফাইলটি নিজেই পরীক্ষা করতে পারবেন। আপনার পরিবর্তনগুলি কিছু না ভেঙেছে তা নিশ্চিত করার দুর্দান্ত দ্রুত উপায়। এটি স্পষ্টতই আপনার সমস্ত শ্রেণীর পরীক্ষার জন্য একটি স্কেলযোগ্য সমাধান তৈরি করে: কেবলমাত্র সেগুলি চালান। (আপনি এটি অন্য একটি অকার্যকর মেইন দিয়ে অন্যান্য ভাষায়ও করতে পারেন যা সর্বদা পাশাপাশি এটির পরীক্ষাও চালায়)।
আমি এখানে একটি স্পষ্ট কোড উদাহরণ তৈরি করতে চাই যা আপনি যে কোনও ক্লাসে ব্যবহার করতে পারেন যেখানে আপনি ব্যক্তিগত পদ্ধতি পরীক্ষা করতে চান।
আপনার পরীক্ষার ক্ষেত্রে শ্রেণিতে কেবল এই পদ্ধতিগুলি অন্তর্ভুক্ত করুন এবং তারপরে ইঙ্গিত অনুসারে এগুলি নিয়োগ করুন।
/**
*
* @var Class_name_of_class_you_want_to_test_private_methods_in
* note: the actual class and the private variable to store the
* class instance in, should at least be different case so that
* they do not get confused in the code. Here the class name is
* is upper case while the private instance variable is all lower
* case
*/
private $class_name_of_class_you_want_to_test_private_methods_in;
/**
* This uses reflection to be able to get private methods to test
* @param $methodName
* @return ReflectionMethod
*/
protected static function getMethod($methodName) {
$class = new ReflectionClass('Class_name_of_class_you_want_to_test_private_methods_in');
$method = $class->getMethod($methodName);
$method->setAccessible(true);
return $method;
}
/**
* Uses reflection class to call private methods and get return values.
* @param $methodName
* @param array $params
* @return mixed
*
* usage: $this->_callMethod('_someFunctionName', array(param1,param2,param3));
* {params are in
* order in which they appear in the function declaration}
*/
protected function _callMethod($methodName, $params=array()) {
$method = self::getMethod($methodName);
return $method->invokeArgs($this->class_name_of_class_you_want_to_test_private_methods_in, $params);
}
$ এটি -> _ কলমেথোড ('_ কিছু ফাংশননাম', অ্যারে (প্যারাম 1, প্যারাম 2, প্যারাম 3));
কেবলমাত্র প্যারামিটারগুলি ক্রম যাতে তারা ব্যক্তিগত ব্যক্তিগত ফাংশনে উপস্থিত হয় তা জারি করুন
যে কোনও ব্যক্তি যেকোন প্রকার কল্পনা ও জঞ্জাল ছাড়াই ব্যক্তিগত পদ্ধতি চালাতে চান For এটি কোনও পুরানো প্রতিবিম্ব ছাড়া আর কিছুই ব্যবহার করে কোনও ইউনিট পরীক্ষার কাঠামোর সাথে কাজ করে।
public class ReflectionTools
{
// If the class is non-static
public static Object InvokePrivate(Object objectUnderTest, string method, params object[] args)
{
Type t = objectUnderTest.GetType();
return t.InvokeMember(method,
BindingFlags.InvokeMethod |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Static,
null,
objectUnderTest,
args);
}
// if the class is static
public static Object InvokePrivate(Type typeOfObjectUnderTest, string method, params object[] args)
{
MemberInfo[] members = typeOfObjectUnderTest.GetMembers(BindingFlags.NonPublic | BindingFlags.Static);
foreach(var member in members)
{
if (member.Name == method)
{
return typeOfObjectUnderTest.InvokeMember(method, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, typeOfObjectUnderTest, args);
}
}
return null;
}
}
তারপরে আপনার আসল পরীক্ষায় আপনি এরকম কিছু করতে পারেন:
Assert.AreEqual(
ReflectionTools.InvokePrivate(
typeof(StaticClassOfMethod),
"PrivateMethod"),
"Expected Result");
Assert.AreEqual(
ReflectionTools.InvokePrivate(
new ClassOfMethod(),
"PrivateMethod"),
"Expected Result");
এমবিউনিত এই রিফ্লেক্টর নামে একটি দুর্দান্ত মোড়ক পেয়েছে।
Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);
আপনি বৈশিষ্ট্য থেকে মান সেট করতে এবং পেতে পারেন
dogReflector.GetProperty("Age");
"ব্যক্তিগত বেসরকারী পরীক্ষার" বিষয়ে আমি সম্মত তা .. নিখুঁত বিশ্বে। বেসরকারী ইউনিট পরীক্ষা করার কোনও মানে নেই। তবে বাস্তব বিশ্বে আপনি হয়ত রিফ্যাক্টরিং কোডের পরিবর্তে ব্যক্তিগত পরীক্ষা লিখতে চান।
Reflector
আরও শক্তিশালী দ্বারা প্রতিস্থাপিত হয়েছে Mirror
। ( gallio.org/wiki/doku.php?id=mbunit:mirror )
ব্যক্তিগত পদ্ধতিগুলির ইউনিট পরীক্ষার বিষয়ে এখানে ভাল নিবন্ধ । তবে আমি নিশ্চিত নই কি আরও ভাল, আপনাকে বিশেষভাবে পরীক্ষার জন্য ডিজাইন করা অ্যাপ্লিকেশন তৈরি করা (এটি কেবল পরীক্ষার জন্য পরীক্ষা তৈরির মতো) বা পরীক্ষার জন্য প্রতিচ্ছবি ব্যবহার করতে। খুব নিশ্চিত যে আমাদের বেশিরভাগই দ্বিতীয় উপায়টি বেছে নেবে।
আমার মতে আপনি কেবল আপনার সংঘর্ষের পাবলিক এপিআই পরীক্ষা করতে হবে।
কোনও পদ্ধতিটিকে জনসম্মুখে তৈরি করার জন্য, এটি পরীক্ষা করার জন্য, এনক্যাপসুলেশনটি বাস্তবায়নের বিশদটি প্রকাশ করে।
একটি ভাল পাবলিক এপিআই ক্লায়েন্ট কোডের একটি তাত্ক্ষণিক লক্ষ্য সমাধান করে এবং সেই লক্ষ্যটিকে পুরোপুরি সমাধান করে।
আমি প্রাইভেটঅবজেক্ট ক্লাস ব্যবহার করি । তবে বেসিক পদ্ধতিগুলি পরীক্ষা করা এড়াতে আগেই ভাল হিসাবে উল্লেখ করা হয়েছে।
Class target = new Class();
PrivateObject obj = new PrivateObject(target);
var retVal = obj.Invoke("PrivateMethod");
Assert.AreEqual(retVal);
CC -Dprivate=public
"সিসি" হ'ল আমি যে সিস্টেমটি ব্যবহার করি তার কমান্ড লাইন সংকলক। -Dfoo=bar
সমতুল্য করে #define foo bar
। সুতরাং, এই সংকলন বিকল্পটি কার্যকরভাবে সমস্ত ব্যক্তিগত স্টাফটিকে জনসাধারণে পরিবর্তন করে।
এখানে একটি উদাহরণ রয়েছে, প্রথমে পদ্ধতিটির স্বাক্ষর:
private string[] SplitInternal()
{
return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
.Cast<Match>()
.Select(m => m.Value)
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
}
পরীক্ষাটি এখানে:
/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
object[] values = new object[] { 2, "Martin" };
XPathString xp = new XPathString(path, values);
PrivateObject param0 = new PrivateObject(xp);
XPathString_Accessor target = new XPathString_Accessor(param0);
string[] expected = new string[] {
"pair[path/to/@Key={0}]",
"Items",
"Item[Name={1}]",
"Date"
};
string[] actual;
actual = target.SplitInternal();
CollectionAssert.AreEqual(expected, actual);
}
এটি করার একটি উপায় হ'ল আপনার পদ্ধতিটি রয়েছে protected
এবং একটি পরীক্ষা স্থিতি লিখুন যা পরীক্ষার জন্য আপনার শ্রেণীর উত্তরাধিকার সূত্রে আসে। এইভাবে, আপনি বা আপনার পদ্ধতিটি ঘুরিয়ে দিচ্ছেন না public
তবে আপনি পরীক্ষাটি সক্ষম করেছেন।
1) আপনার যদি লিগ্যাসি কোড থাকে তবে ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করার একমাত্র উপায় হ'ল প্রতিচ্ছবি।
2) এটি যদি নতুন কোড হয় তবে আপনার নিম্নলিখিত বিকল্পগুলি রয়েছে:
আমি এ্যানোটেশন পদ্ধতিটি পছন্দ করি, সহজতম এবং অন্তত জটিল। একমাত্র বিষয়টি হ'ল আমরা দৃশ্যমানতা বৃদ্ধি করেছি যা আমি মনে করি এটি বড় উদ্বেগ নয়। আমাদের সর্বদা ইন্টারফেসে কোডিং করা উচিত, সুতরাং আমাদের যদি একটি ইন্টারফেস মাই সার্ভিস এবং একটি বাস্তবায়ন মাই সার্ভিসআইএমপিএল থাকে তবে আমাদের সাথে সম্পর্কিত টেস্ট ক্লাসগুলি মাই সার্ভিস টেস্ট (টেস্ট ইন্টারফেস পদ্ধতি) এবং মাই সার্ভিসআইম্প্লিটেষ্ট (পরীক্ষার ব্যক্তিগত পদ্ধতি) হতে পারে। সমস্ত ক্লায়েন্টকে যেভাবেই হোক ইন্টারফেসটি এমনভাবে ব্যবহার করা উচিত যদিও প্রাইভেট পদ্ধতির দৃশ্যমানতা বাড়ানো হয়েছে তা আসলেই বিবেচ্য নয়।
ডিবাগ-মোডে তৈরি করার সময় আপনি এটিকে সর্বজনীন বা অভ্যন্তরীণ হিসাবেও ঘোষণা করতে পারেন (ইন্টার্নালভিজিবলটোঅ্যাট্রিবিউট সহ):
/// <summary>
/// This Method is private.
/// </summary>
#if DEBUG
public
#else
private
#endif
static string MyPrivateMethod()
{
return "false";
}
এটি কোডটি ফুলে যায় তবে এটি private
একটি রিলিজ বিল্ডে থাকবে।
আপনি ভিজ্যুয়াল স্টুডিও ২০০৮ থেকে প্রাইভেট পদ্ধতির জন্য পরীক্ষা পদ্ধতি তৈরি করতে পারেন you আপনি যখন কোনও ব্যক্তিগত পদ্ধতির জন্য ইউনিট পরীক্ষা তৈরি করেন, তখন একটি পরীক্ষা রেফারেন্স ফোল্ডারটি আপনার পরীক্ষার প্রকল্পে যুক্ত হয় এবং সেই ফোল্ডারে একটি এক্সেসর যুক্ত করা হয়। অ্যাক্সেসরটিকে ইউনিট পরীক্ষা পদ্ধতির যুক্তিতেও উল্লেখ করা হয়। এই অ্যাক্সেসরটি আপনার ইউনিট পরীক্ষাটি কোডের মধ্যে ব্যক্তিগত পদ্ধতিতে কল করতে অনুমতি দেয় যা আপনি পরীক্ষা করছেন। বিস্তারিত জানার জন্য দেখুন
এছাড়াও নোট করুন যে ইন্টারনালভিজিবলটিওআর্ট্রিবিউটের আপনার সমাবেশটি শক্তিশালী নামকরণের একটি প্রয়োজনীয়তা রয়েছে , যা আপনি যদি এমন কোনও সমাধানে কাজ করে যা এর আগে তার প্রয়োজনীয়তা ছিল না তবে এটি নিজের সমস্যা তৈরি করে। আমি ব্যক্তিগত পদ্ধতি পরীক্ষা করতে অ্যাকসেসরটি ব্যবহার করি। এটির উদাহরণ হিসাবে এই প্রশ্নটি দেখুন ।
InternalsVisibleToAttribute
নেই না প্রয়োজন, আপনার সমাহারগুলি জোরালোভাবে নামে। আমি বর্তমানে এটি এমন একটি প্রকল্পে ব্যবহার করছি যেখানে এটির ক্ষেত্রে নেই।
pre-historic
ইন্টারনেট ইন্টারনেট বছরের ক্ষেত্রে, তবে ব্যক্তিগত পদ্ধতিগুলির ইউনিট টেস্টিং এখন সহজ এবং সোজা এগিয়ে উভয়ই, যখন ভিজুয়াল স্টুডিও প্রয়োজনীয় অ্যাক্সেসর ক্লাস উত্পাদন করে এবং প্রয়োজন হয় প্রাক-ভরাট পরীক্ষার যুক্তি স্নিপেটের সাথে অভিশাপ দিয়ে যে কেউ সাধারণ কার্যকরী পরীক্ষার জন্য যা চাইবে তার কাছাকাছি। যেমন দেখুন। msdn.microsoft.com/en-us/library/ms184807%28VS.90%29.aspx