我有一個單元測試,我試圖驗證我已經處理過一次附加到主用戶界面的文檔。單元測試必須是異步的,因爲一切都需要在STA線程下運行,我必須等待創建的用戶界面。我做錯了什麼結合dotMemory,xUnit和異步
我有一個幫助器,將操作分派到STA線程。
我在測試的主體中創建了內存對象,然後將其傳遞給下面的異步方法。
查看用評論的代碼行###查看實際問題行。 dotMemory報告該對象不存在,但我已經做出了證明對象確實存在的斷言。
(STA Helper類可以在https://gist.github.com/bradphelan/cb4f484fbf6a7f9829de0dd52036fd63找到)
這是做異步和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。 async one failed and sync one pass。
[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.Check調用,但dotMemory告訴我,我試圖運行並行測試。 – bradgonesurfing
獲取對象是否運行異步? –
不,它不。 – bradgonesurfing