I'm unit testing some asynchronous code. I have tried to abstract it to make the issue more clear. My issue is that I want to set up the mocked Bar
to execute Foo
's private callback method after BeginWork
returns. The callback is supposed to call Set()
on the ManualResetEvent
allowing the calling thread to continue to run. When I run the test my thread blocks indefinitely at the call to WaitOne()
.
Code under test:
using System.Threading;
using NUnit.Framework;
using Moq;
using System.Reflection;
public interface IBar
{
int BeginWork(AsyncCallback callback);
}
public class Bar : IBar
{
public int BeginWork(AsyncCallback callback)
{
// do stuff
} // execute callback
}
public class Foo
{
public static ManualResetEvent workDone = new ManualResetEvent(false);
private IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
public bool DoWork()
{
bar.BeginWork(new AsyncCallback(DoWorkCallback));
workDone.WaitOne(); // thread blocks here
return true;
}
private void DoWorkCallback(int valueFromBeginWork)
{
workDone.Set();
}
}
Test Code:
[Test]
public void Test()
{
Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
// get private callback
MethodInfo callback = typeof(Foo).GetMethod("DoWorkCallback",
BindingFlags.Instance | BindingFlags.NonPublic);
mockBar.Setup(() => BeginWork(It.IsAny<AsyncCallback>()))
.Returns(0).Callback(() => callback.Invoke(0));
Foo = new Foo(mockBar.Object);
Assert.That(Foo.DoWork());
}