我正在尝试测试从我的Nancy应用程序返回的模型是否与预期的一样。我跟踪了docs 这里,但是每当我调用GetModel<T>扩展方法时,它都会抛出一个KeyNotFoundException。
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.我知道这个错误意味着什么,但我不明白为什么要抛出它。
这是我的模块
public class SanityModule : NancyModule
{
public SanityModule()
{
Get["sanity-check"] = _ => Negotiate.WithModel(new SanityViewModel { Id = 1 })
.WithStatusCode(HttpStatusCode.OK);
}
}我的视图模型
public class SanityViewModel
{
public int Id { get; set; }
}这是我的测试
[TestFixture]
public class SanityModuleTests
{
[Test]
public void Sanity_Check()
{
// Arrange
var browser = new Browser(with =>
{
with.Module<SanityModule>();
with.ViewFactory<TestingViewFactory>();
});
// Act
var result = browser.Get("/sanity-check", with =>
{
with.HttpRequest();
with.Header("accept", "application/json");
});
var model = result.GetModel<SanityViewModel>();
// Asset
model.Id.ShouldBeEquivalentTo(1);
}
}调试此测试表明,该模块已命中并完成良好。运行应用程序将显示响应与预期的相同。
有人能解释一下这件事吗?
发布于 2014-09-04 09:32:07
感谢那些可爱的家伙,阿尔贝詹和the.fringe.ninja,在南希·贾布尔房间中,我们对这里发生的事情有了一个解释。
TL;DR这是有意义的,但错误信息应该更具描述性。下面有个解决办法。
这里的问题是,在使用application/json时,我以TestingViewFactory的身份请求响应。
让我们来看看GetModel<T>();的实现
public static TType GetModel<TType>(this BrowserResponse response)
{
return (TType)response.Context.Items[TestingViewContextKeys.VIEWMODEL];
}这只是从NancyContext中获取视图模型,并将其转换为您的类型。这是引发错误的地方,因为在NancyContext.中没有视图模型。这是因为视图模型是在NancyContext的RenderView方法中添加到TestingViewFactory中的。
public Response RenderView(string viewName, dynamic model, ViewLocationContext viewLocationContext)
{
// Intercept and store interesting stuff
viewLocationContext.Context.Items[TestingViewContextKeys.VIEWMODEL] = model;
viewLocationContext.Context.Items[TestingViewContextKeys.VIEWNAME] = viewName;
viewLocationContext.Context.Items[TestingViewContextKeys.MODULENAME] = viewLocationContext.ModuleName;
viewLocationContext.Context.Items[TestingViewContextKeys.MODULEPATH] = viewLocationContext.ModulePath;
return this.decoratedViewFactory.RenderView(viewName, model, viewLocationContext);
}我的测试请求json,所以不会调用RenderView。这意味着只有在使用html请求时才能使用GetModel<T>。
解决方案
我的应用程序是一个api,所以我没有任何视图可以更改行。
with.Header("accept", "application/json");至
with.Header("accept", "text/html");会抛出一个ViewNotFoundException。为了避免这种情况,我需要实现我自己的IViewFactory。(这来自the.fringe.ninja)
public class TestViewFactory : IViewFactory
{
#region IViewFactory Members
public Nancy.Response RenderView(string viewName, dynamic model, ViewLocationContext viewLocationContext)
{
viewLocationContext.Context.Items[Fixtures.SystemUnderTest.ViewModelKey] = model;
return new HtmlResponse();
}
#endregion
}那么,这只是一个更新的例子。
with.ViewFactory<TestingViewFactory>();至
with.ViewFactory<TestViewFactory>();现在,GetModel<T>应该可以工作,而不需要视图。
https://stackoverflow.com/questions/25652619
复制相似问题