首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >南希测试GetModel<T>抛出KeyNotFoundException

南希测试GetModel<T>抛出KeyNotFoundException
EN

Stack Overflow用户
提问于 2014-09-03 19:54:20
回答 1查看 492关注 0票数 4

我正在尝试测试从我的Nancy应用程序返回的模型是否与预期的一样。我跟踪了docs 这里,但是每当我调用GetModel<T>扩展方法时,它都会抛出一个KeyNotFoundException

代码语言:javascript
复制
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

我知道这个错误意味着什么,但我不明白为什么要抛出它。

这是我的模块

代码语言:javascript
复制
public class SanityModule : NancyModule
{
    public SanityModule()
    {
        Get["sanity-check"] = _ => Negotiate.WithModel(new SanityViewModel { Id = 1 })
                                            .WithStatusCode(HttpStatusCode.OK);
    }
}

我的视图模型

代码语言:javascript
复制
public class SanityViewModel
{
    public int Id { get; set; }
}

这是我的测试

代码语言:javascript
复制
[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);
    }
}

调试此测试表明,该模块已命中并完成良好。运行应用程序将显示响应与预期的相同。

有人能解释一下这件事吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-04 09:32:07

感谢那些可爱的家伙,阿尔贝詹the.fringe.ninja,在南希·贾布尔房间中,我们对这里发生的事情有了一个解释。

TL;DR这是有意义的,但错误信息应该更具描述性。下面有个解决办法。

这里的问题是,在使用application/json时,我以TestingViewFactory的身份请求响应。

让我们来看看GetModel<T>();的实现

代码语言:javascript
复制
public static TType GetModel<TType>(this BrowserResponse response)
{
    return (TType)response.Context.Items[TestingViewContextKeys.VIEWMODEL];
}

这只是从NancyContext中获取视图模型,并将其转换为您的类型。这是引发错误的地方,因为在NancyContext.中没有视图模型。这是因为视图模型是在NancyContext的RenderView方法中添加到TestingViewFactory中的。

代码语言:javascript
复制
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,所以我没有任何视图可以更改行。

代码语言:javascript
复制
with.Header("accept", "application/json");

代码语言:javascript
复制
with.Header("accept", "text/html");

会抛出一个ViewNotFoundException。为了避免这种情况,我需要实现我自己的IViewFactory。(这来自the.fringe.ninja)

代码语言:javascript
复制
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
}

那么,这只是一个更新的例子。

代码语言:javascript
复制
with.ViewFactory<TestingViewFactory>();

代码语言:javascript
复制
with.ViewFactory<TestViewFactory>();

现在,GetModel<T>应该可以工作,而不需要视图。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25652619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档