ঠিক আছে - নিম্নলিখিতগুলি আপনার পক্ষে কোনও উপকারে আসবে কিনা তা সম্পর্কে আমি নিশ্চিত নই, কারণ এমন একটি সমাধান বিকাশে আমি কিছু অনুমান করেছি যা আপনার ক্ষেত্রে সত্য হতে পারে বা নাও হতে পারে। হতে পারে আমার "সমাধান" খুব তাত্ত্বিক এবং কেবল কৃত্রিম উদাহরণগুলির জন্য কাজ করে - আমি নীচের স্টাফের বাইরে কোনও পরীক্ষা করিনি।
তদতিরিক্ত, আমি নিম্নলিখিতটি বাস্তব সমাধানের চেয়ে আরও কার্যকরভাবে দেখতে পাব তবে প্রতিক্রিয়াগুলির অভাব বিবেচনা করে আমি মনে করি এটি এখনও কোনওটির চেয়ে ভাল হতে পারে (আমি আপনার প্রশ্নটি সমাধানের জন্য অপেক্ষা করতে দেখলাম, তবে পোস্ট হওয়া দেখে না দেখে আমি খেলতে শুরু করেছি) সমস্যাটি নিয়ে প্রায়)।
তবে যথেষ্ট বলেছিলেন: আসুন আমরা বলি যে আমাদের কাছে একটি সাধারণ ডেটা পরিষেবা রয়েছে যা একটি পূর্ণসংখ্যা পুনরুদ্ধারে ব্যবহার করা যেতে পারে:
public interface IDataService
{
Task<int> LoadMagicInteger();
}
একটি সাধারণ বাস্তবায়ন অ্যাসিক্রোনাস কোড ব্যবহার করে:
public sealed class CustomDataService
: IDataService
{
public async Task<int> LoadMagicInteger()
{
Console.WriteLine("LoadMagicInteger - 1");
await Task.Delay(100);
Console.WriteLine("LoadMagicInteger - 2");
var result = 42;
Console.WriteLine("LoadMagicInteger - 3");
await Task.Delay(100);
Console.WriteLine("LoadMagicInteger - 4");
return result;
}
}
এখন, একটি সমস্যা দেখা দিয়েছে, যদি আমরা এই শ্রেণীর দ্বারা বর্ণিত কোডটি "ভুলভাবে" ব্যবহার করি। ফলাফলের মতো করে আইনের পরিবর্তে Foo
ভুলভাবে অ্যাক্সেস করে:Task.Result
await
Bar
public sealed class ClassToTest
{
private readonly IDataService _dataService;
public ClassToTest(IDataService dataService)
{
this._dataService = dataService;
}
public async Task<int> Foo()
{
var result = this._dataService.LoadMagicInteger().Result;
return result;
}
public async Task<int> Bar()
{
var result = await this._dataService.LoadMagicInteger();
return result;
}
}
আমাদের (আপনার) এখন যা দরকার তা হল একটি পরীক্ষা লেখার একটি উপায় যা কল করার সময় সফল হয় Bar
তবে কল করার সময় ব্যর্থ হয় Foo
(কমপক্ষে যদি আমি প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে ;-))।
আমি কোডটি বলতে দেব; আমি এখানে যা এলাম তা এখানে (ভিজ্যুয়াল স্টুডিও টেস্ট ব্যবহার করে, তবে এটি NUnit ব্যবহার করেও কাজ করা উচিত):
DataServiceMock
ব্যবহার TaskCompletionSource<T>
। এটি আমাদের পরীক্ষার রানের একটি নির্ধারিত সময়ে ফলাফল নির্ধারণ করতে দেয় যা নিম্নলিখিত পরীক্ষার দিকে নিয়ে যায়। মনে রাখবেন যে আমরা একটি প্রতিনিধিকে টাস্ককম্পশনসোর্সটি পরীক্ষায় ফিরে পাস করতে ব্যবহার করছি। আপনি এটিকে পরীক্ষার আরম্ভের পদ্ধতিতে ব্যবহার করতে এবং বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন।
TaskCompletionSource<int> tcs = null;
this._dataService.LoadMagicIntegerMock = t => tcs = t;
Task<int> task = null;
TaskTestHelper.AssertDoesNotBlock(() => task = this._instance.Foo());
tcs.TrySetResult(42);
var result = task.Result;
Assert.AreEqual(42, result);
this._end = true;
এখানে যা ঘটছে তা হ'ল আমরা প্রথমে যাচাই করেছিলাম যে আমরা অবরুদ্ধকরণ ছাড়াই পদ্ধতিটি ছেড়ে দিতে পারি (যদি কারও অ্যাক্সেস করা হয় তবে এটি কাজ করবে না Task.Result
- এক্ষেত্রে আমরা পদ্ধতিটি ফিরে না আসা পর্যন্ত কাজের ফলাফল উপলব্ধ না করা হয় বলে আমরা একটি সময়সীমার মধ্যে চলে যাব )।
তারপরে, আমরা ফলাফলটি নির্ধারণ করি (এখন পদ্ধতিটি কার্যকর করতে পারে) এবং আমরা ফলাফলটি যাচাই করি (ইউনিট পরীক্ষার অভ্যন্তরে আমরা টাস্ক অ্যাক্সেস করতে পারি ult ফলাফল হিসাবে আমরা বাস্তবে অবরুদ্ধ হওয়া চাই ) es
সম্পূর্ণ পরীক্ষার শ্রেণি - পছন্দ হিসাবে BarTest
সাফল্য ও FooTest
ব্যর্থতা।
[TestClass]
public class UnitTest1
{
private DataServiceMock _dataService;
private ClassToTest _instance;
private bool _end;
[TestInitialize]
public void Initialize()
{
this._dataService = new DataServiceMock();
this._instance = new ClassToTest(this._dataService);
this._end = false;
}
[TestCleanup]
public void Cleanup()
{
Assert.IsTrue(this._end);
}
[TestMethod]
public void FooTest()
{
TaskCompletionSource<int> tcs = null;
this._dataService.LoadMagicIntegerMock = t => tcs = t;
Task<int> task = null;
TaskTestHelper.AssertDoesNotBlock(() => task = this._instance.Foo());
tcs.TrySetResult(42);
var result = task.Result;
Assert.AreEqual(42, result);
this._end = true;
}
[TestMethod]
public void BarTest()
{
TaskCompletionSource<int> tcs = null;
this._dataService.LoadMagicIntegerMock = t => tcs = t;
Task<int> task = null;
TaskTestHelper.AssertDoesNotBlock(() => task = this._instance.Bar());
tcs.TrySetResult(42);
var result = task.Result;
Assert.AreEqual(42, result);
this._end = true;
}
}
ডেডলকস / সময়সীমা পরীক্ষা করার জন্য একটি সামান্য সহায়ক শ্রেণি:
public static class TaskTestHelper
{
public static void AssertDoesNotBlock(Action action, int timeout = 1000)
{
var timeoutTask = Task.Delay(timeout);
var task = Task.Factory.StartNew(action);
Task.WaitAny(timeoutTask, task);
Assert.IsTrue(task.IsCompleted);
}
}
async
নিবন্ধের সংকলনটি পড়েছেন ?