私は一度メインのユーザーインターフェイスに添付された文書を廃棄したことを確認しようとするユニットテストをしています。単体テストは、すべてがSTAスレッドの下で実行される必要があるという点で非同期でなければならず、作成されるユーザーインターフェイスを待たなければなりません。dotMemory、xUnit、asyncを組み合わせて間違ったことをしていますか?
私は、STAスレッドにアクションをディスパッチするヘルパーを持っています。
私はメモリオブジェクトをテスト本体に作成し、それを以下のように非同期メソッドに渡します。
実際の問題行を表示するには、###とコメントされたコード行を参照してください。 dotMemoryはオブジェクトがまだ存在しないと報告していますが、オブジェクトが存在することを証明するアサーションをすでに作成しています。
(STAヘルパークラスは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);
}
}
上記の同じテストの同期バージョンが作成されており、失敗しません。以下の2つのテストがあります。ShouldCollectAsyncおよびShouldCollectSync。 非同期が失敗し、がを1つ通過します。
[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呼び出しを入れようとしましたが、並列テストを実行しようとしています。 – bradgonesurfing
オブジェクトは非同期で実行されますか? –
いいえ、そうではありません。 – bradgonesurfing