Having coded an extension method (based on GUI update when starting event handler class on separate thread?):
public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult> (this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
if (control.InvokeRequired)
return (TResult)control.Invoke (func, control);
return func (control);
}
}
I've been trying to unit test this method both from a UI thread and a normal thread and I can't seem to be able to achieve that.
Here is the unit test code:
[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
// Prepare
string result = string.Empty;
var form = new Form ();
var thread = new Thread (() =>
{
result = form.InvokeEx (f => f.Text);
});
// Execute
thread.Start ();
thread.Join (1000);
// Verify
Assert.That (result, Is.EqualTo ("Some label"));
}
The test passes but if I set a breakpoint in the InvokeEx method (not the call) I see that Control.InvokeRequired is false resulting in the func method directly called.
Furthermore, now the test fails because result is not set.
Additionally, while stepping through the code I see that the func method is executed on the other thread (as expected) and not on the main thread.
Maybe it is because I do not have a real UI thread since I am executing a unit test? How would I achieve that and all the message pumping?
I've been trying different things and I've come up with the following:
[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
// Prepare
string result = string.Empty;
var form = new Form ();
var uiThread = new Thread (() => Application.Run (form));
uiThread.SetApartmentState (ApartmentState.STA);
uiThread.Start();
Thread.Sleep (100);
var thread = new Thread (() => result = form.InvokeEx (f => f.Text));
// Execute
thread.Start ();
thread.Join ();
form.InvokeEx (f => f.Close ());
uiThread.Join ();
// Verify
Assert.That (result, Is.EqualTo ("Some label"));
}
This now works perfectly.
Note that I had to add an overload for InvokeEx for a void method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With