ブレッドクラム ノードのタイトルを、ユーザーが見ている項目の値に変更するコントローラー アクションがいくつかあります。
[MvcSiteMapNode(Title = "{0}", ParentKey = "Maintenance-Settings-Index", Key = "Maintenance-Settings-Details", PreservedRouteParameters = "id", Attributes = "{\"visibility\":\"SiteMapPathHelper,!*\"}")]
public async Task<ActionResult> Details(int id)
{
var model = await GetSetting(id);
var node = SiteMaps.Current.CurrentNode;
if (node != null)
{
node.Title = string.Format("{0}", model.Name);
}
return View(model);
}
これは、サイトを通常どおり表示している場合は正常に機能し、希望どおりに動作します..
ただし... Moq と FluentMVCTesting を使用してコントローラーのアクションを単体テストしようとすると、エラーが発生します。
http://www.shiningtreasures.com/post/2013/08/14/mvcsitemapprovider-4-unit-testing-with-the-sitemaps-static-methodsからSiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
例を追加しました
コントローラー コンテキストを作成する
private static ControllerContext FakeControllerContext(RouteData routeData)
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new MockHttpSession();
var server = new Mock<HttpServerUtilityBase>();
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session);
context.Setup(ctx => ctx.Server).Returns(server.Object);
var controllerContext = new ControllerContext(context.Object, routeData ?? new RouteData(), new Mock<ControllerBase>().Object);
return controllerContext;
}
テストごとにコントローラーを初期化する
[TestInitialize]
public void Initialize()
{
var routeData = new RouteData();
_controller = new DepartmentSettingsController
{
ControllerContext = FakeControllerContext(routeData)
};
}
次に、テスト自体
[TestMethod]
public void Details()
{
SiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
_controller.WithCallTo(c => c.Details(_model.Id)).ShouldRenderDefaultView()
.WithModel<SettingViewModel>(m => m.Name == _model.Name);
}
次のエラーが発生しますSystem.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。これはvar node = SiteMaps.Current.CurrentNode;
次に、別のテストを追加します
[TestMethod]
public void Edit()
{
SiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
_controller.WithCallTo(c => c.Edit(_model.Id)).ShouldRenderDefaultView()
.WithModel<SettingViewModel>(m => m.Name == _model.Name);
}
MvcSiteMapProvider.MvcSiteMapExceptionを取得します。サイトマップ ローダーは、Global.asax の Application_Start イベントでのみ設定でき、再度設定することはできません。外部依存性注入コンテナーを使用している場合は、web.config ファイルの AppSettings セクションの「MvcSiteMapProvider_UseExternalDIContainer」を「true」に設定します。MvcSiteMapProvider.SiteMaps.set_Loader (ISiteMapLoader 値) で
次にSiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
、テストの初期化に移ります。
[TestInitialize]
public void Initialize()
{
var routeData = new RouteData();
_controller = new DepartmentSettingsController
{
ControllerContext = FakeControllerContext(routeData)
};
SiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
}
同じエラーMvcSiteMapProvider.MvcSiteMapException: サイトマップ ローダーは、Global.asax の Application_Start イベントでのみ設定でき、再度設定することはできません。外部依存性注入コンテナーを使用している場合は、web.config ファイルの AppSettings セクションの「MvcSiteMapProvider_UseExternalDIContainer」を「true」に設定します。MvcSiteMapProvider.SiteMaps.set_Loader (ISiteMapLoader 値) で
SiteMaps.Loader = new Mock<ISiteMapLoader>().Object;
質問 -複数のアクションをテストする場合、単体テストで最適な場所はどこですか
質問 -var node = SiteMaps.Current.CurrentNode;
コントローラーで静的を使用するのが最善の方法ですか、それともより良い方法がありますか(Unity を使用)
ご協力いただきありがとうございます