C# 单元测试控制调用问题
本文关键字:问题 调用 控制 单元测试 | 更新日期: 2023-09-27 18:32:17
我已经为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)(() =>
感谢您的任何帮助!
问题是,在上面的示例中,当前线程被阻止,但控件想要在此线程上调用。
解决方案是将其他事件 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));
}
希望这对某人有帮助。