使用 AutoFixture 对 Html 助手进行单元测试

2024-02-17

我正在尝试使用 AutoFixture 对 Html Helper 进行单元测试。下面是我的SUT

public static MvcHtmlString SampleTable(this HtmlHelper helper,
    SampleModel model, IDictionary<string, object> htmlAttributes)
{
    if (helper == null)
    {
        throw new ArgumentNullException("helper");
    }
    if (model == null)
    {
        throw new ArgumentNullException("model");
    }

    TagBuilder tagBuilder = new TagBuilder("table");
    tagBuilder.MergeAttributes(htmlAttributes);
    tagBuilder.GenerateId(helper.ViewContext.HttpContext.Items[Keys.SomeKey].ToString());
    return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}

正如您所看到的,它只返回一个 MVC Html 字符串,其中带有表标签和附加的 Id。 (参见下面的单元测试结果示例)

使用 AutoFixture 进行单元测试:

[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
    var fixture = new Fixture();

    //Arrange
    fixture.Inject<HttpContextBase>(new FakeHttpContext());
    var httpContext = fixture.CreateAnonymous<HttpContextBase>();
    fixture.Inject<ViewContext>(new ViewContext());
    var vc = fixture.CreateAnonymous<ViewContext>();

    vc.HttpContext = httpContext;
    vc.HttpContext.Items.Add(Keys.SomeKey, "foo");

    fixture.Inject<IViewDataContainer>(new FakeViewDataContainer());
    var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
    var sampleModel = fixture.CreateAnonymous<SampleModel>();

    //Act
    var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();

    //Assert
    Assert.Equal("<table id=\"foo\"></table>", result);
}      

FakeHttpContext 和 FakeViewDataContainer 只是 HttpContextBase 和 IViewDataContainer 的假实现。

该测试通过并返回预期结果。然而,我不确定我是否正确使用了 Autofixture。是否有更好的方法在此单元测试中使用 AutoFixture?


根据部分信息,很难确切地说出如何进一步减少上述测试,但我猜测它可以减少。

首先,调用组合Inject其次是CreateAnonymous这是相当惯用的——特别是如果你颠倒顺序的话。这就是所谓的Freezing http://blog.ploeh.dk/2010/03/17/AutoFixtureFreeze.aspx匿名值(相当于 DI 容器的 Singleton 生命周期范围)。可以这样更简洁地表述:

var vc = fixture.Freeze<ViewContext>();

测试似乎也将 HttpContext 映射到 FakeHttpContext。映射可以更容易一些 http://blog.ploeh.dk/2010/04/06/MappingTypesWithAutoFixture.aspx,但这会映射 Transient 实例......

无论如何,除非您有令人信服的理由使用手动 Mocks 而不是动态 Mock 库 http://msdn.microsoft.com/en-us/magazine/cc163358.aspx,您不妨决定使用AutoFixture 作为自动模拟容器 http://blog.ploeh.dk/2010/08/19/AutoFixtureAsAnAutomockingContainer.aspx。这可能会让你摆脱很多这种类型的映射。

所以,鉴于这一切,我会guess您也许可以将测试简化为如下所示:

[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());

    //Arrange
    var vc = fixture.Freeze<ViewContext>();
    vc.HttpContext.Items.Add(Keys.SomeKey, "foo");

    var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
    var sampleModel = fixture.CreateAnonymous<SampleModel>();

    //Act
    var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();

    //Assert
    Assert.Equal("<table id=\"foo\"></table>", result);
}

但是,大部分 Arrange 部分现在是纯粹声明性的,并且由于您似乎已经在使用 xUnit.net,因此您可以使用AutoFixture 的 AutoData 理论 http://blog.ploeh.dk/2010/10/08/AutoDataTheoriesWithAutoFixture.aspx将大部分变量移至方法参数:

[Theory, AutoMoqData]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml(
    [Frozen]ViewContext vc,
    HtmlHelper htmlHelper,
    SampleModel sampleModel)
{
    //Arrange
    vc.HttpContext.Items.Add(Keys.SomeKey, "foo");

    //Act
    var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();

    //Assert
    Assert.Equal("<table id=\"foo\"></table>", result);
}

假设您已将 AutoMoqCustomization 与 AutoDataAttribute 桥接起来,如下所示:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute :
        base(new Fixture().Customize(new AutoMoqCustomization()))
    { }
}

请记住,您可能需要稍微调整上面的代码以使其适合您的 API 的详细信息。这只是一个草图。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 AutoFixture 对 Html 助手进行单元测试 的相关文章

  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 未找到 ID 为“android”的插件(Android Studio)

    我最近刚刚切换到 Android Studio 0 6 1 进行应用程序开发 并且遇到了 gradle 问题 I get Error 1 0 Plugin with id android not found 我很新 所以任何帮助将不胜感激
  • 使一个相当复杂的 Django 模型方法可以在管理中排序?

    我有一个相当复杂的自定义 Django 模型方法 它在管理界面中可见 我现在想让它在管理界面中也可排序 我已经添加admin order field按照推荐在上一个问题中 https stackoverflow com questions
  • 为什么我的导航栏不居中?

    我一直在尝试一切方法来尝试将这个导航栏居中 但它从来没有这样做 文本对齐不起作用 margin 0 auto 也不起作用 我尝试尽可能多地添加它以覆盖所有空间 因为无论如何它都不起作用 这是 HTML div class nav div c
  • Groovy:如何调用带注释的方法

    我在几个类中的某些方法的顶部粘贴了一个注释 MyAnnotation 如下所示 FirstClass MyAnnotation doSomethingWith String text println text from first clas
  • 带有 Speex 编码音频的 FLV 文件示例?

    谁能给我提供一个带有 Speex 编码配乐的 Flash 视频文件示例 可以从网络上的某个位置免费下载 视频可以采用任何编解码器 最好没有 我正在尝试开发一个应用程序来以编程方式生成此类文件 并且希望有一个有效的示例与我的输出进行比较以进行
  • 使用 numpy.genfromtxt() 跳过指定数量的列

    我有一个大表 文本格式的数字 我想加载它numpy genfromtxt 我想忽略第一个n列数 例如 5 我事先不知道表的大小 行数或列数 我看到了genfromtxt 有一个选项skip header允许跳过指定数量的标题行 但似乎列没有
  • ServiceStack API和ASP MVC两种认证方式

    我在解决通过 ServiceStack 提供 html 页面和 Web 服务的 ASP MVC 应用程序的体系结构时遇到问题 应用程序位于基本 url 中 例如 http myapplication com http myapplicati
  • SQLCLR - 包装 COM 调用

    我正在尝试调用一个 net 程序集 该程序集包装了来自 Sql Server 的一些 COM 调用 对第三方 dll 程序集注册正常 我尝试使用不安全和外部访问进行注册 但是当我运行该过程时 出现此错误 执行用户定义例程或聚合 Manage
  • 如何使用 Fluent NHibernate 和多个数据库识别特定实体的会话工厂

    问题来自流畅的NHibernate 多个数据库 https stackoverflow com questions 2655861 fluent nhibernate multiple databases 无需点击此链接 这里应该有足够的背
  • 在 OpenCv、Python 中保存相同图像时无法获得与原始图像相同的颜色[重复]

    这个问题在这里已经有答案了 我编写了一段代码来旋转图像并保存它们 所以我使用OpenCv来保存旋转图像 保存旋转后的图像后 图像上会变成蓝色 操作系统 Ubuntu 16 04 这是代码 from scipy ndimage import
  • C++ 未解析的外部[重复]

    这个问题在这里已经有答案了 有谁知道这意味着什么 1 gt Generating Code 1 gt BlankWindowDXbaseImpl obj error LNK2019 unresolved external symbol pu
  • 如何更改垫扩展面板的切换图标?

    用于切换的默认图标mat expansion panel is gt 环境hideToggletrue 只是隐藏切换图标 有什么办法可以改变吗 我在官方文档中没有找到任何内容 我想用 or 图标 如果状态分别为关闭或打开 如 Angular
  • Laravel 5.4 ‘cross-env’ 不被识别为内部或外部命令

    我正在尝试奔跑npm run dev对于 Laravel Mix 我收到此错误 gt dev D projects ptcs gt cross env NODE ENV development webpack progress hide m
  • 主题错误 - 如何修复?

    尝试了很多解决方案但没有帮助 Ref 无法在当前主题中找到样式 coordinatorLayoutStyle https stackoverflow com questions 49292487 failed to find style c
  • JQuery Mobile
  • 文本长度
  • 我正在使用 JQuery Mobile 并且有一个 li 带有一些长文本 描述 我的问题是它只显示几个单词 后面跟着 3 个点 请问怎样才能让它显示整个字符串 您可以使用 JQMobile 中提到的格式docs http jquerymob
  • 实现多个接口的类的清晰度(替代委托):

    假设我们有以下内容 IFirst Interface IUnknown function GetStuff Integer end ISecond Interface IUnknown function GetOtherStuff Inte
  • 谷歌地图API。获取该国家所在的洲

    有一个简单的google API查询 响应包含边界 位置和完整地址 例如 俄罗斯 但我现在需要 俄罗斯 gt 欧洲 美国 gt 北美 埃及 gt 非洲 怎么做 使用 Google API 进行地理编码 中的条目之一 address comp
  • 按日期间隔索引数据帧

    我有一个数据框 其中一列包含 数百个日期格式的日期 例如 as Date c 2011 08 13 2011 09 13 2010 06 12 2012 09 13 2010 09 13 2012 05 26 2012 07 20 现在我只
  • Rails 中的 ActiveModel - 视图 - 控制器而不是 ActiveRecord?

    我尝试对我的模型使用 ActiveModel 而不是 ActiveRecord 因为我不希望我的模型与数据库有任何关系 下面是我的模型 class User include ActiveModel Validations validates
  • 使用 AutoFixture 对 Html 助手进行单元测试

    我正在尝试使用 AutoFixture 对 Html Helper 进行单元测试 下面是我的SUT public static MvcHtmlString SampleTable this HtmlHelper helper SampleM