সম্পাদনা করুন : মোখ ৪.১০ তে আপনি এখন একটি ডেলিগেট পাস করতে পারেন যার কলব্যাক ফাংশনে সরাসরি আউট বা রেফ প্যারামিটার রয়েছে:
mock
.Setup(x=>x.Method(out d))
.Callback(myDelegate)
.Returns(...);
আপনাকে একটি প্রতিনিধি নির্ধারণ করতে হবে এবং তা ইনস্ট্যান্ট করতে হবে:
...
.Callback(new MyDelegate((out decimal v)=>v=12m))
...
মক সংস্করণের জন্য ৪.১০ এর আগে:
আভনার কাশতান তার ব্লগে একটি এক্সটেনশন পদ্ধতি সরবরাহ করে যা কলব্যাক থেকে আউট প্যারামিটার সেট করার অনুমতি দেয়: মক, কলব্যাকস এবং আউট প্যারামিটারগুলি: একটি বিশেষত কঠিন প্রান্তের কেস
সমাধান মার্জিত এবং হ্যাকি উভয়ই। মার্জিত এতে এটি একটি সাবলীল সিনট্যাক্স সরবরাহ করে যা ঘরে ঘরে অন্য মক কলব্যাকের সাথে অনুভব করে। এবং হ্যাকি কারণ এটি প্রতিবিম্বের মাধ্যমে কিছু অভ্যন্তরীণ মাক এপিআই কল করার উপর নির্ভর করে।
উপরের লিঙ্কটিতে প্রদত্ত এক্সটেনশন পদ্ধতিটি আমার জন্য সংকলন করেনি, তাই আমি নীচে সম্পাদিত সংস্করণ সরবরাহ করেছি। আপনার কাছে থাকা প্রতিটি ইনপুট প্যারামিটারের জন্য আপনাকে একটি স্বাক্ষর তৈরি করতে হবে; আমি 0 এবং 1 সরবরাহ করেছি তবে এটিকে আরও বাড়ানো সহজ হওয়া উচিত:
public static class MoqExtensions
{
public delegate void OutAction<TOut>(out TOut outVal);
public delegate void OutAction<in T1,TOut>(T1 arg1, out TOut outVal);
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, TOut>(this ICallback<TMock, TReturn> mock, OutAction<TOut> action)
where TMock : class
{
return OutCallbackInternal(mock, action);
}
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, TOut>(this ICallback<TMock, TReturn> mock, OutAction<T1, TOut> action)
where TMock : class
{
return OutCallbackInternal(mock, action);
}
private static IReturnsThrows<TMock, TReturn> OutCallbackInternal<TMock, TReturn>(ICallback<TMock, TReturn> mock, object action)
where TMock : class
{
mock.GetType()
.Assembly.GetType("Moq.MethodCall")
.InvokeMember("SetCallbackWithArguments", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, mock,
new[] { action });
return mock as IReturnsThrows<TMock, TReturn>;
}
}
উপরের এক্সটেনশন পদ্ধতিতে, আপনি আউট প্যারামিটারগুলির সাথে একটি ইন্টারফেস পরীক্ষা করতে পারেন যেমন:
public interface IParser
{
bool TryParse(string token, out int value);
}
.. নিম্নলিখিত Moq সেটআপ সহ:
[TestMethod]
public void ParserTest()
{
Mock<IParser> parserMock = new Mock<IParser>();
int outVal;
parserMock
.Setup(p => p.TryParse("6", out outVal))
.OutCallback((string t, out int v) => v = 6)
.Returns(true);
int actualValue;
bool ret = parserMock.Object.TryParse("6", out actualValue);
Assert.IsTrue(ret);
Assert.AreEqual(6, actualValue);
}
সম্পাদনা করুন : অকার্যকর-রিটার্ন পদ্ধতিগুলি সমর্থন করতে, আপনাকে কেবল নতুন ওভারলোড পদ্ধতি যুক্ত করতে হবে:
public static ICallbackResult OutCallback<TOut>(this ICallback mock, OutAction<TOut> action)
{
return OutCallbackInternal(mock, action);
}
public static ICallbackResult OutCallback<T1, TOut>(this ICallback mock, OutAction<T1, TOut> action)
{
return OutCallbackInternal(mock, action);
}
private static ICallbackResult OutCallbackInternal(ICallback mock, object action)
{
mock.GetType().Assembly.GetType("Moq.MethodCall")
.InvokeMember("SetCallbackWithArguments", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, mock, new[] { action });
return (ICallbackResult)mock;
}
এটি পরীক্ষামূলক ইন্টারফেসগুলি যেমন:
public interface IValidationRule
{
void Validate(string input, out string message);
}
[TestMethod]
public void ValidatorTest()
{
Mock<IValidationRule> validatorMock = new Mock<IValidationRule>();
string outMessage;
validatorMock
.Setup(v => v.Validate("input", out outMessage))
.OutCallback((string i, out string m) => m = "success");
string actualMessage;
validatorMock.Object.Validate("input", out actualMessage);
Assert.AreEqual("success", actualMessage);
}
It.IsAny<T>()
-একটি মিলকারীর (ref It.Ref<T>.IsAny
স্থাপনের জন্য সমর্থন করার জন্য).Callback()
এবং.Returns()
পদ্ধতি স্বাক্ষর মিলে একটি কাস্টম প্রতিনিধি ধরনের মাধ্যমে। সুরক্ষিত পদ্ধতিগুলি সমানভাবে সমর্থিত। যেমন নীচে আমার উত্তর দেখুন ।