テストしたい既存のレガシーコードがあります。要点の再現は次のとおりです。
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;
}
}
現在、このレガシー ユニットにはいくつかの問題がありますが、今のところはテストを行っているところです。具体的には、 を上げた場合に呼び出されcollaborator.DoOtherStuff
ないことをテストしたい。Response.End()
ThreadAbort
問題: どうやってそのような例外を発生させるのですか?
でこの質問とその回答を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
あまりにもテストに不向きですか?
完全で最小限の再現 (NUnit 2.6.4 および Moq 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);
}
}