c# – 我在做dotMemory,xUnit和async时做错了什么
发布时间:2020-12-15 22:38:06 所属栏目:百科 来源:网络整理
导读:我有一个单元测试,我试图验证我已经处理了一个曾经附加到主用户界面的文档.单元测试必须是异步的,因为一切都需要在STA线程下运行,我必须等待创建的用户界面. 我有一个帮助程序将动作调度到STA线程. 我在测试的主体中创建了内存对象,然后将其传递给异步方法,
我有一个单元测试,我试图验证我已经处理了一个曾经附加到主用户界面的文档.单元测试必须是异步的,因为一切都需要在STA线程下运行,我必须等待创建的用户界面.
我有一个帮助程序将动作调度到STA线程. 我在测试的主体中创建了内存对象,然后将其传递给异步方法,如下所示. 请参阅使用###注释的代码行以查看实际问题行. dotMemory报告该对象尚不存在,但我已经做了一个断言,证明该对象确实存在. (STA Helper课程可在https://gist.github.com/bradphelan/cb4f484fbf6a7f9829de0dd52036fd63找到) 这与async和dotMemory有关吗? [Collection("Memory leaks")] public class MemLeakSpec { public MemLeakSpec(ITestOutputHelper output) { DotMemoryUnitTestOutput.SetOutputMethod(output.WriteLine); } [Fact] [DotMemoryUnit(FailIfRunWithoutSupport = true)] public void ShouldCollectProjectX() { dotMemory.Check (memory => { STAThread.Run(() => ShouldCollectProjectAsyncX(memory)).Wait(); }); } class Document { } class Container { public Document Document; }; Document CreateFoo() => new Document(); private async Task ShouldCollectProjectAsyncX(Memory memory) { await Task.Delay(TimeSpan.FromMilliseconds(50)); Container container = new Container(); memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(0); Document documentA = CreateFoo(); container.Document = documentA; // Verify with dotMemory that the object exists. // ### This fails even though I have verified // ### the document exists memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(1); // Open a new project which should dispose the old one and thus // remove any reference to GenericWeinCadFolder container.Document = null; memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(0); GC.KeepAlive(container); } } 我已经创建了相同的上述测试的同步版本,它不会失败.在ShouldCollectAsync和ShouldCollectSync下面有两个测试.异步的一个失败,同步一个通过. [Collection("Memory leaks")] public class MemLeakSpec { public MemLeakSpec(ITestOutputHelper output) { DotMemoryUnitTestOutput.SetOutputMethod(output.WriteLine); } [Fact] [DotMemoryUnit(FailIfRunWithoutSupport = true)] public void ShouldCollectAsync() { dotMemory.Check (memory => { STAThread.Run(() => ShouldCollectProjectAsyncX(memory)).Wait(); }); } /// This test is almost identical to the ShouldCollectAsync /// but it passes [Fact] [DotMemoryUnit(FailIfRunWithoutSupport = true)] public void ShouldCollectSync () { dotMemory.Check (memory => { STAThread.Run(() => ShouldCollectProjectSync(memory)); }); } class Document { } class Container { public Document Document; }; Document CreateFoo() => new Document(); private async Task ShouldCollectProjectSync(Memory memory) { Container container = new Container(); memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(0); Document documentA = CreateFoo(); container.Document = documentA; // Verify with dotMemory that the object exists. // #### Passes here memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(1); GC.KeepAlive(documentA); GC.KeepAlive(container); } private async Task ShouldCollectProjectAsyncX(Memory memory) { await Task.Delay(TimeSpan.FromMilliseconds(50)); Container container = new Container(); memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(0); Document documentA = CreateFoo(); container.Document = documentA; // Verify with dotMemory that the object exists. // #### FAILS here memory.GetObjects(@where => @where.Type.Is<Document>()) .ObjectsCount.Should() .Be(1); GC.KeepAlive(documentA); GC.KeepAlive(container); } } 解决方法
dotMemory Unit要求应该从“test”方法调用其所有方法. 想想就像在一开始就调用dotMemoryUnit.TestStart一样 在完成时,应该收集Async和dotMemoryUnit.TestEnd. 你没有公开STAThread.Run的实现,所以我不能给出更详细的建议,但是想法是在async例程完成时等待测试方法.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |