如何从测试项目同步 运行 方法(无等待)
How to run method synchronously from test project (no await)
我对使用 Task 和围绕它的整个概念还很陌生。我还使用 Net 4.0(Office 2007 的 VSTO 开发)
我想了解我在我的应用程序中写的一件事,它正在生产中工作,但为它编写单元测试最终使用 Thread.Sleep
并检查任务是否 运行 完成或不是
背景
生产代码非常简单,它调用一个服务来检查环境状态(PROD、STAGE、QA 等)它在(void
) 方法通过 Task
,在任务体内它设置了一个正在更新 UI (WPF) 的 属性 并且它工作正常。请注意,我没有在该方法中使用 Wait
。如果任务失败,我将继续执行另一个 OnlyOnFaulted
问题
我尝试对方法进行单元测试 (void) 所以我想 运行 方法 运行ning 同步 但我失败了那里。
我读到 RunSynchronously,也看到有人使用任务。Result
(4.0 似乎不可用), 也试过 Scheduler.Current
, AttachedToParent
等等
我认为问题出在我的设计上,我想我正在尝试调用一个方法并说 "Hey, run synchronously" 它确实如此,但在方法内部是另一个 运行 async 的任务所以不管它总是 运行 异步的。我对吗?有没有办法在我的测试项目中没有循环并等待 RunToCompletion
?
来测试它
这是我为了更好地理解而创建的示例代码,我对其进行了一些简化。在实际实施中,我的解决方案中有一个适当的测试项目,我正在模拟该服务,因此它不会调用真实的服务等。
namespace ConsoleApplication1
{
public class Program
{
static void Main(string[] args)
{
ImagineThisIsInTestProject();
Console.ReadLine();
Console.WriteLine("Started");
var cls = new Program();
cls.MyProdMethod();
Console.WriteLine("Finished");
Console.ReadLine();
}
public string Status { get; private set; }
public void MyProdMethod()
{
// I have more logic in my real method, serialization, handling errors
Console.WriteLine("In my method");
var task = Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None);
Console.WriteLine("Finishing my method");
}
public static void ImagineThisIsInTestProject()
{
Console.WriteLine("TEST started");
var sut = new Program();
var task = new Task(() => sut.MyProdMethod());
task.RunSynchronously(); // I would assume this will wait until the task is finished?
// here my assert if status is set
Console.WriteLine($"Status is - {sut.Status}");
Console.WriteLine("TEST finished");
}
}
}
上面的输出是
TEST started
In my method
Finishing my method
Status is -
TEST finished
Setting status
Started
In my method
Finishing my method
Finished
Setting status
您无法真正测试您的方法 public void MyProdMethod()
因为:
var task = Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None);
基本上是一火就忘了
除非您等待任务完成,否则无法对此进行测试。我知道您不想包含 Wait 但要测试请考虑以下内容:
public void MyProdMethod()
{
// I have more logic in my real method, serialization, handling errors
Console.WriteLine("In my method");
Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None).Wait();
Console.WriteLine("Finishing my method");
}
然后您的测试将如下所示:
[TestClass]
public class TestClass
{
[TestMethod]
public void Test()
{
// Arrange
var program = new Program();
// Act
program.MyProdMethod();
// Assert
Assert.AreEqual("Yes I set it", program.Status);
}
}
如果您退出 Wait,测试将在方法中的任务有机会完成之前完成,因此导致断言失败。
我对使用 Task 和围绕它的整个概念还很陌生。我还使用 Net 4.0(Office 2007 的 VSTO 开发)
我想了解我在我的应用程序中写的一件事,它正在生产中工作,但为它编写单元测试最终使用 Thread.Sleep
并检查任务是否 运行 完成或不是
背景
生产代码非常简单,它调用一个服务来检查环境状态(PROD、STAGE、QA 等)它在(void
) 方法通过 Task
,在任务体内它设置了一个正在更新 UI (WPF) 的 属性 并且它工作正常。请注意,我没有在该方法中使用 Wait
。如果任务失败,我将继续执行另一个 OnlyOnFaulted
问题
我尝试对方法进行单元测试 (void) 所以我想 运行 方法 运行ning 同步 但我失败了那里。
我读到 RunSynchronously,也看到有人使用任务。Result
(4.0 似乎不可用), 也试过 Scheduler.Current
, AttachedToParent
等等
我认为问题出在我的设计上,我想我正在尝试调用一个方法并说 "Hey, run synchronously" 它确实如此,但在方法内部是另一个 运行 async 的任务所以不管它总是 运行 异步的。我对吗?有没有办法在我的测试项目中没有循环并等待 RunToCompletion
?
这是我为了更好地理解而创建的示例代码,我对其进行了一些简化。在实际实施中,我的解决方案中有一个适当的测试项目,我正在模拟该服务,因此它不会调用真实的服务等。
namespace ConsoleApplication1
{
public class Program
{
static void Main(string[] args)
{
ImagineThisIsInTestProject();
Console.ReadLine();
Console.WriteLine("Started");
var cls = new Program();
cls.MyProdMethod();
Console.WriteLine("Finished");
Console.ReadLine();
}
public string Status { get; private set; }
public void MyProdMethod()
{
// I have more logic in my real method, serialization, handling errors
Console.WriteLine("In my method");
var task = Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None);
Console.WriteLine("Finishing my method");
}
public static void ImagineThisIsInTestProject()
{
Console.WriteLine("TEST started");
var sut = new Program();
var task = new Task(() => sut.MyProdMethod());
task.RunSynchronously(); // I would assume this will wait until the task is finished?
// here my assert if status is set
Console.WriteLine($"Status is - {sut.Status}");
Console.WriteLine("TEST finished");
}
}
}
上面的输出是
TEST started
In my method
Finishing my method
Status is -
TEST finished
Setting status
Started
In my method
Finishing my method
Finished
Setting status
您无法真正测试您的方法 public void MyProdMethod()
因为:
var task = Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None);
基本上是一火就忘了
除非您等待任务完成,否则无法对此进行测试。我知道您不想包含 Wait 但要测试请考虑以下内容:
public void MyProdMethod()
{
// I have more logic in my real method, serialization, handling errors
Console.WriteLine("In my method");
Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Console.WriteLine("Setting status");
Status = "Yes I set it";
}, CancellationToken.None).Wait();
Console.WriteLine("Finishing my method");
}
然后您的测试将如下所示:
[TestClass]
public class TestClass
{
[TestMethod]
public void Test()
{
// Arrange
var program = new Program();
// Act
program.MyProdMethod();
// Assert
Assert.AreEqual("Yes I set it", program.Status);
}
}
如果您退出 Wait,测试将在方法中的任务有机会完成之前完成,因此导致断言失败。