私はテスト中のレガシーコードを手に入れました。ここでは必需品のREPROです:レガシーコードが特定の方法でThreadAbortExceptionに反応するというユニットテスト
今public class LegacyUnit
{
private readonly ICollaborator collaborator;
public LegacyUnit(ICollaborator collaborator)
{
this.collaborator = collaborator;
}
public object GetStuff(HttpContextBase context, string input)
{
try
{
if (input == "")
{
context.Response.End();
}
collaborator.DoOtherStuff();
return "Done!";
}
catch (ThreadAbortException)
{ }
return null;
}
}
、このレガシーユニットは、いくつかの問題がありますが、今の私は、テストの下でそれを取得しようとしています。具体的には、がThreadAbort
の場合collaborator.DoOtherStuff
がではなく、であることをテストしたいと考えています。
問題:このような例外はどのように発生させますか?
私はthis question and its answers on ThreadAbortException
まで読んで、それが特別だと理解しています。しかし、私はこれらの記事からユニットテストでこれをどう扱うかは分かりません。
[Test]
public void DoesNotCallCollaboratorOnThreadAbort()
{
var testResponseMock = new Mock<HttpResponseBase>();
var testContextMock = new Mock<HttpContextBase>();
var collaboratorMock = new Mock<ICollaborator>();
testContextMock.Setup(x => x.Response).Returns(testResponseMock.Object);
testResponseMock.Setup(x => x.End()).Throws<ThreadAbortException>(); // Compile error
var unit = new LegacyUnit(collaboratorMock.Object);
unit.GetStuff(testContextMock.Object, "");
collaboratorMock.Verify(c => c.DoOtherStuff(), Times.Never);
}
明らかに、コンパイラは文句:ThreadAbortException
は、使用可能なコンストラクタを持っていない
は、ここに私の試みです。また、それはsealed
です(おそらく理由があるため)、 "テスト可能な"サブクラスの作成は機能しません。
テスト中にこのようなコードを取得する適切な方法は何ですか?それは実現可能なのでしょうか、またはLegacyUnit
もあまりにもテストに不満ですか?
フル、最小限のREPRO(NUnitの2.6.4および4.5.9部品番号と空の.NET 4.5のクラスライブラリ):
public interface ICollaborator
{
void DoOtherStuff();
}
public class LegacyUnit
{
private readonly ICollaborator collaborator;
public LegacyUnit(ICollaborator collaborator)
{
this.collaborator = collaborator;
}
public object GetStuff(HttpContextBase context, string input)
{
try
{
if (input == "") context.Response.End();
collaborator.DoOtherStuff();
return "Done!";
}
catch (ThreadAbortException)
{ }
return null;
}
}
[TestFixture]
public class LegacyUnitTests
{
[Test]
public void DoesNotCallCollaboratorOnThreadAbort()
{
var testResponseMock = new Mock<HttpResponseBase>();
var testContextMock = new Mock<HttpContextBase>();
var collaboratorMock = new Mock<ICollaborator>();
testContextMock.Setup(x => x.Response).Returns(testResponseMock.Object);
testResponseMock.Setup(x => x.End()).Throws<ThreadAbortException>(); // Compile error here
var unit = new LegacyUnit(collaboratorMock.Object);
unit.GetStuff(testContextMock.Object, "");
collaboratorMock.Verify(c => c.DoOtherStuff(), Times.Never);
}
}
End()が任意のタイプの例外をスローすると、DoOtherStuffも実行されません。 – Jehof
真。私の実際のケースでは、他の種類の例外を巡って、いろいろなことが起こっています。可能であれば最小限のレプロを行うには、完全性を犠牲にしなければならなかった。 – Jeroen