私が取り組んでいるプロジェクトでは、ついにプロジェクトの一部の SpecFlow 機能テストを作成するところまで来ました。
ただし、小さな問題が 1 つあります。アプリには、一部のテストで呼び出す必要がある Authorization フィルターがあります。
承認フィルターは次のようになります (ここでは多くの編集が行われています)。
public class Authorization : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if(filterContext == null
|| filterContext.Controller == null
|| filterContext.Controller.ControllerContext == null)
throw new ArgumentException("Incomplete filter context.");
if(! filterContext.Controller.ControllerContext.IsChildAction)
{
if(filterContext.RequestContext == null
|| filterContext.RequestContext.HttpContext == null
|| filterContext.RequestContext.HttpContext.Request == null
|| filterContext.RequestContext.HttpContext.Request.Url == null)
throw new ArgumentException("Incomplete request in filter context.");
// SNIP: Authorization checks and activities.
// This one line is a bit tricky to mock...
HttpRequestBase request = filterContext.HttpContext.Request;
// SNIP: Other activities that come after
}
}
// SNIP: Other supporting methods that don't pertain to the problem domain.
}
...そして、私の機能テストでは、特別な指定されたステップでそれを呼び出そうとしています:
[Given(@"I am logged in as (.*)")]
public void GivenIAmLoggedInAsX(string userId)
{
_controller = new SpecificController();
_controller.ControllerContext = new ControllerContext(new HttpContextMock(), new RouteData(), _controller);
Authorization authorize = new Authorization();
AuthorizeContext authContext = new AuthorizationContext(_controller.ControllerContext);
authorize.OnAuthorization(authContext);
// SNIP: Other activities that don't pertain to the question.
}
NotImplementedExceptions
...私が構築しているテストケースで多くを生成することにより、これは機能しませんでした。
私のチームに尋ねた後、誰かControllerActionInvoker
が MVC のクラスについて言及しました。悲しいことに、MS のドキュメントは、それをどのように使用するのが最善かなど、詳細について少し粗雑です。
また、StackOverflow も、ControllerActionInvoker の使用方法を理解しようとして失敗しました。 WayBack Machineもあまり役に立ちませんでした。
結果が得られず、多くの欲求不満が生じた暫定措置として、いくつかの異なる方法を試しました.
質問:作業中の機能テストでこのフィルターを呼び出す必要があり、直接的な方法ではうまくいきません。機能テスト用のフィルターを呼び出す最良の方法は何ですか?
補足: MVC フィルタリング システム全体は、私にとって未知の領域なので、知らないことがたくさんあります。あなたの答えでは、これを行う方法について私が行った調査でも、おそらく正確であるため、私はほとんど何も知らないと仮定します。
代替実装 #1
私の元の例では、古いコンストラクターが使用されていることがわかりました。代わりに推奨される 2 引数のコンストラクターがあります。だから、私はそれを使っても効果がありませんでした。これがどのように見えるかです(まだ直接的なアプローチです:)
[Given(@"I am logged in as (.*)")]
public void GivenIAmLoggedInAsX(string userId)
{
_controller = new RequestFormController();
_controller.ControllerContext = new ControllerContext(new HttpContextMock(), new RouteData(), _controller);
Authorization authorize = new Authorization();
MethodInfo method = typeof (MyController).GetMethod("MyAction");
ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(typeof(MyController));
ActionDescriptor actionDescriptor = new ReflectedActionDescriptor(method, "MyAction", controllerDescriptor);
AuthorizationContext authContext = new AuthorizationContext(_controller.ControllerContext, actionDescriptor);
authorization.OnAuthorization(authContext);
// SNIP: Unrelated code.
}