我已经为WinForms应用编写了单元测试。应用程序在线程中执行代码,该代码在UI上设置结果。为此,我必须通过Control.Invoke(delegate)
在UI线程中调用结果集。在应用程序中它完美。在单元测试中,我必须等待异步结果。但是,在单元测试中Control.Invoke(delegate)
没有发射。
我没有线程问题。线程在单元测试中完美运行。问题是在UI线程上调用一个线程。有人提示,它是如何工作的。
为了重现这个问题,我创建了一个示例WinForms项目和一个单元测试项目。表单包含一个文本框和一个按钮。通过单击按钮,它启动一个线程,等待两秒钟并在文本框中设置文本。设置文本后,它会触发一个事件。
这是Forms类:
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
}
private void btnAction_Click(object sender, EventArgs e)
{
this.SetText();
}
public delegate void delFinish();
public event delFinish Finish;
public void SetText()
{
Thread runner = new Thread(() => {
Thread.Sleep(2000);
if (this.txtResult.InvokeRequired)
this.txtResult.Invoke((MethodInvoker)(() =>
{
this.txtResult.Text = "Runner";
if (Finish != null)
Finish();
}));
else
{
this.txtResult.Text = "Runner";
if (Finish != null)
Finish();
}
});
runner.Start();
}
}
这是单元测试:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
ManualResetEvent finished = new ManualResetEvent(false);
TestForm form = new TestForm();
form.Finish += () => {
finished.Set();
};
form.SetText();
Assert.IsTrue(finished.WaitOne());
Assert.IsTrue(!string.IsNullOrEmpty(form.txtResult.Text));
}
}
问题是这一行不会执行:
this.txtResult.Invoke((MethodInvoker)(() =>
感谢您的帮助!
答案 0 :(得分:0)
问题是,在上面的示例中,当前线程被阻止,但是在该线程上,控件想要调用。
解决方案是将其他事件Application.DoEvents()并执行到另一个线程Thread.Yield()。
测试方法如下:
[TestMethod]
public void TestMethod1()
{
bool finished = false;
TestForm form = new TestForm();
form.Finish += () =>
{
finished = true;
};
form.SetText();
while (!finished)
{
Application.DoEvents();
Thread.Yield();
}
Assert.IsTrue(!string.IsNullOrEmpty(form.txtResult.Text));
}
希望这对某人有帮助。