The other day I was pairing with a colleague. We where working on unit testing some classes that where using the new async and await features. We ran into some issue trying to get mocking working for our classes dependencies. Here is some example code on how we got things to work.
So given the following code:
public interface IClass2
{
Task<string> GetSomeString_MethodAsync();
}
public class Class2 : IClass2
{
public async Task<string> GetSomeString_MethodAsync()
{
await Task.Run(() => Thread.Sleep(2000));
return "hello world.";
}
}
public class Class1
{
private IClass2 class2;
public Class1(IClass2 class2)
{
this.class2 = class2;
}
public async Task<string> SomeMethod()
{
return await this.class2.GetSomeString_MethodAsync();
}
}
{
Task<string> GetSomeString_MethodAsync();
}
public class Class2 : IClass2
{
public async Task<string> GetSomeString_MethodAsync()
{
await Task.Run(() => Thread.Sleep(2000));
return "hello world.";
}
}
public class Class1
{
private IClass2 class2;
public Class1(IClass2 class2)
{
this.class2 = class2;
}
public async Task<string> SomeMethod()
{
return await this.class2.GetSomeString_MethodAsync();
}
}
And we can test it like this:
private Mock<IClass2> class2Mock;
private Class1 class1;
[TestInitialize]
public void Setup()
{
this.class2Mock = new Mock<IClass2>();
this.class1 = new Class1(this.class2Mock.Object);
}
[TestMethod]
public async Task SomeMethodTest()
{
var expectedString = "Hello World";
var tcs = new TaskCompletionSource<string>();
tcs.SetResult(expectedString);
this.class2Mock.Setup(x => x.GetSomeString_MethodAsync()).Returns(tcs.Task);
var result = await this.class1.SomeMethod();
Assert.AreEqual(result, expectedString);
}
private Class1 class1;
[TestInitialize]
public void Setup()
{
this.class2Mock = new Mock<IClass2>();
this.class1 = new Class1(this.class2Mock.Object);
}
[TestMethod]
public async Task SomeMethodTest()
{
var expectedString = "Hello World";
var tcs = new TaskCompletionSource<string>();
tcs.SetResult(expectedString);
this.class2Mock.Setup(x => x.GetSomeString_MethodAsync()).Returns(tcs.Task);
var result = await this.class1.SomeMethod();
Assert.AreEqual(result, expectedString);
}
Note the usage of the TaskCompletionSource in the unit test along with the declaration of the test using “async Task”.
"TaskCompletionSource", exactly what I needed for my mocking! Thank you Dave.
ReplyDeleteThanks so much for this blog post. I was languishing for hours trying to figure out how to mock up an await method.
ReplyDelete6 years old but what the heck.. You can simplify by using Task.FromResult(expectedString)instead of the TaskCompletionSource.
ReplyDeletePERDE MODELLERİ
ReplyDeleteSMS ONAY
mobil ödeme bozdurma
nft nasıl alınır
ankara evden eve nakliyat
trafik sigortası
Dedektor
web sitesi kurma
aşk kitapları
smm panel
ReplyDeletesmm panel
iş ilanları blog
instagram takipçi satın al
hirdavatciburada.com
Www.beyazesyateknikservisi.com.tr
Servis
tiktok jeton hile