仅当在构建服务器上运行时单元测试才会失败

2024-03-09

为了帮助单元测试,我们已经完成了DateTime委托中的类,以便DateTime.Now可以在单元测试中被覆盖。

public static class SystemTime
{
    #region Static Fields

    public static Func<DateTime> Now = () => DateTime.Now;

    #endregion
}

下面是它在 xunit 单元测试中的使用示例:

[Fact]
public void it_should_update_the_last_accessed_timestamp_on_an_entry()
{
    // Arrange
    var service = this.CreateClassUnderTest();

    var expectedTimestamp = SystemTime.Now();
    SystemTime.Now = () => expectedTimestamp;

    // Act
    service.UpdateLastAccessedTimestamp(this._testEntry); 

    // Assert
    Assert.Equal(expectedTimestamp, this._testEntry.LastAccessedOn);
}   

测试在本地运行良好,但是在我们的构建服务器上失败,因为日期时间不同Assert陈述。

我正在努力思考它会失败的原因DateTime通过上述委托包装器进行模拟。我已经确认执行中没有问题UpdateLastAccessedTimestamp方法,并且在本地运行时测试通过。

不幸的是我无法在我们的构建服务器上调试它。有什么想法为什么它仅在构建服务器上运行时才会失败?

请注意,执行UpdateLastAccessedTimestamp如下:

public void UpdateLastAccessedTimestamp(Entry entry)
{
    entry.LastAccessedOn = SystemTime.Now();
    this._unitOfWork.Entries.Update(entry);
    this._unitOfWork.Save();
}

The Entry类只是一个简单的 POCO 类,它有许多字段,包括LastAccessedOn field:

public class Entry
{
   public DateTime LastAccessedOn { get; set; }

   //other fields that have left out to keep the example concise
}

您的问题可能是由于多个单元测试与static SystemTime。例如,如果您有类似的内容:

单元测试1

[Fact]
public void it_should_update_the_last_accessed_timestamp_on_an_entry()
{
    // Arrange
    var service = this.CreateClassUnderTest();

    var expectedTimestamp = SystemTime.Now();
    SystemTime.Now = () => expectedTimestamp;

    // Act
    service.UpdateLastAccessedTimestamp(this._testEntry); 

    // Assert
    Assert.Equal(expectedTimestamp, this._testEntry.LastAccessedOn);
}   

public void UpdateLastAccessedTimestamp(Entry entry)
{
    entry.LastAccessedOn = SystemTime.Now();
    this._unitOfWork.Entries.Update(entry);
    this._unitOfWork.Save();
}

单元测试2

[Fact]
public void do_something_different
{
    SystemTime.Now = () => DateTime.Now;
}

因此,我们假设单元测试 2(全部)在单元测试 1 的两行之间触发:

SystemTime.Now = () => expectedTimestamp;

// Unit test 2 starts execution here

// Act
service.UpdateLastAccessedTimestamp(this._testEntry); 

如果发生这种情况,那么你的UpdateLastAccessedTimestamp不会(必然)达到您的预期DateTime您设置的值SystemTime.Now = () => expectedTimestamp;,因为另一个测试已经覆盖了您在单元测试 1 中提供的函数。

这就是为什么我认为你最好要么通过DateTime作为参数,或使用可注入的日期时间:

/// <summary>
/// Injectable DateTime interface, should be used to ensure date specific logic is more testable
/// </summary>
public interface IDateTime
{
    /// <summary>
    /// Current Data time
    /// </summary>
    DateTime Now { get; }
}

/// <summary>
/// DateTime.Now - use as concrete implementation
/// </summary>
public class SystemDateTime : IDateTime
{
    /// <summary>
    /// DateTime.Now
    /// </summary>
    public DateTime Now { get { return DateTime.Now; } }
}

/// <summary>
/// DateTime - used to unit testing functionality around DateTime.Now (externalizes dependency on DateTime.Now
/// </summary>
public class MockSystemDateTime : IDateTime
{
    private readonly DateTime MockedDateTime;

    /// <summary>
    /// Take in mocked DateTime for use in testing
    /// </summary>
    /// <param name="mockedDateTime"></param>
    public MockSystemDateTime(DateTime mockedDateTime)
    {
        this.MockedDateTime = mockedDateTime;
    }

    /// <summary>
    /// DateTime passed from constructor
    /// </summary>
    public DateTime Now { get { return MockedDateTime; } }
}

使用这种情况,您的服务类可能会发生以下变化:

public class Service
{
    public Service() { }

    public void UpdateLastAccessedTimestamp(Entry entry)
    {
        entry.LastAccessedOn = SystemTime.Now();
        this._unitOfWork.Entries.Update(entry);
        this._unitOfWork.Save();
    }
}

To this:

    public class Service
    {

        private readonly IDateTime _iDateTime;

        public Service(IDateTime iDateTime)
        {
            if (iDateTime == null)
                throw new ArgumentNullException(nameof(iDateTime));
            // or you could new up the concrete implementation of SystemDateTime if not provided

            _iDateTime = iDateTime;
        }

        public void UpdateLastAccessedTimestamp(Entry entry)
        {
            entry.LastAccessedOn = _iDateTime.Now;
            this._unitOfWork.Entries.Update(entry);
            this._unitOfWork.Save();
        }           
    }

为了您的实际实施Service你可以像这样进行更新(或使用 IOC 容器):

Service service = new Service(new SystemDateTime());

为了进行测试,您可以使用模拟框架或您的模拟类:

Service service = new Service(new MockDateTime(new DateTime(2000, 1, 1)));

你的单元测试可能会变成:

[Fact]
public void it_should_update_the_last_accessed_timestamp_on_an_entry()
{
    // Arrange
    MockDateTime mockDateTime = new MockDateTime(new DateTime 2000, 1, 1);
    var service = this.CreateClassUnderTest(mockDateTime);

    // Act
    service.UpdateLastAccessedTimestamp(this._testEntry); 

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

仅当在构建服务器上运行时单元测试才会失败 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用

随机推荐

  • 如何设置 WebMatrix/Razor 响应的内容类型?

    我想在我的 WebMatrix cshtml 文件中返回一些 XML 而不是 HTML 如何更改内容类型标头 使用 cshtml 文件顶部的 Response ContentType 属性 然后将 XML 包含在视图的内容中 Respons
  • 如何计算文本的真实SHA1?

    As in 我的最后一个问题 https stackoverflow com q 48327289 287948 参见那里的详细信息 我正在使用 SELECT encode digest x text bytea sha1 hex FROM
  • 检查 UITextView 中的文本是否由于自动换行而换行

    如何检查文本是否在UITextView由于自动换行而转到下一行 我目前有代码来检查用户是否输入新行 从键盘 BOOL textView UITextView textView shouldChangeTextInRange NSRange
  • 使用 OpenCV 时找不到模块 cv2

    我已经安装了OpenCV https en wikipedia org wiki OpenCV在 Raspberry Pi 上的 Occidentalis 操作系统 Raspbian 的一个变体 上 使用这个脚本 https github
  • Graphql 和往返。这只是ios应用程序的问题吗?

    我正在重新审视 graphql 我试图理解为什么节省往返对开发人员有好处 提出请求的费用这么贵吗 我有网络开发背景 让我们将标准 Rest api 与 graphql api 进行比较 我需要检索用户的个人信息及其朋友列表 传统的 Rest
  • 在 jQuery UI 中触发鼠标拖动

    使用 jQuery 1 2 x 和 jQuery UI 1 5 x 可以像这样手动触发拖动 jQuery myDiv mousedown function ev target jQuery ev target if target hasCl
  • Laravel 5 销毁所有用户会话并强制注销

    有没有办法销毁所有会话 我需要注销所有用户 想知道 astrisan 是否可以做到这一点 谢谢你 这实际上取决于您选择的会话驱动器 如果您使用文件驱动器 您可以删除storage framework sessions path 如果您使用数
  • PHP 匿名函数与 array_walk

    我尝试将 array walk 与匿名函数一起使用 但总是收到错误 Parse error syntax error unexpected T FUNCTION in on line X if empty myArray array wal
  • Chrome 和 Firefox 中的 WebSocket 在不活动一分钟后断开连接

    我发现 Chrome 和 Firefox 中的 WebSocket 在闲置一分钟后就会断开连接 根据我在网上看到的内容 我完全将责任归咎于代理或某些服务器设置或其他东西 但在 IE 或 Edge 中不会发生这种情况 看起来如果套接字在一分钟
  • 在数据库中存储长字符串好吗?

    我需要在数据库中存储长字符串 该字符串可能有 5 或 6 个句子长 您认为这是一个很好的设计策略吗 或者我应该存储该字符串的 id 然后创建与另一个包含存储该字符串的文件位置的表的关系 您能给出两者的优点和缺点吗 字符串已被预处理并存储在数
  • 具有命令行历史记录和制表符补全功能的 mit-scheme REPL

    我正在阅读SICP http mitpress mit edu sicp full text book book html我正在使用mit scheme http www gnu org software mit scheme 通过以下方式
  • WebAPI传递的post参数为null

    我正在使用 WebAPI 2 进行测试 并且创建了以下控制器方法 POST api values public string Post FromBody string value string returnValue Return valu
  • 基本的多对多左连接查询

    所以我有3张表 users 成就 Achievements unlocked 多对多 我想要一个查询返回所有可用的成就 并提及当前用户 例如 id user 123 已解锁的成就 我怎样才能做到这一点 这应该涉及左连接 但如果我添加 WHE
  • AngularJS 文件夹结构 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何为大型且可扩展的 AngularJS 应用程序布局文件夹结构 按类型排序 左侧是按类型组织的应用程序 对于较小的应用程序来说还不错 但即使在
  • 无法在关闭时从模态中删除数据。每次都显示相同的内容

    无法在关闭时从模态中删除数据 每次都显示相同的内容 body on hidden bs modal modal function this removeData bs modal 这个功能也不起作用 当我将数据传递到相同的模式并删除内容时
  • 十六进制颜色如何工作?

    代表CSS颜色的十六进制是什么意思 在不记住确切代码的情况下如何知道它是什么颜色 它与RGB 和CMYK 系统有什么关系吗 我想了一下FF means 255RGB 但后来我意识到 15 2 不是 255 而是 225 十六进制使用十六个不
  • 捆绑包格式无法识别、无效或不合适

    代码 8 1 语言 Objective C 我可以在 iPhone 上运行该项目 但无法在模拟器上运行 I tried 1 删除DerivedData文件夹的所有数据 2 清理项目并重新启动项目 3 删除资源文件夹 但这没有用 对于那些无法
  • PHP 中的正则表达式重复捕获组

    我正在尝试从一个带有路线的文件中获取信息 因此对于这项工作 我选择了正则表达式 但我遇到了重复信息的问题 为了做一个更好的问题 我将把我拥有的内容和我想要的内容放在一起 所以我有一个文件 Codes C Connected S Static
  • 如何在 scala 中按 Ordered 参数化 Int

    我有一个具有参数化类型的类 我想对其进行比较运算符 我认为我需要使用 Ordered 特征来实现这一点 但编译器不喜欢我使用它 假设我有以下课程 class Test T lt Ordered T def someOp t T if t l
  • 仅当在构建服务器上运行时单元测试才会失败

    为了帮助单元测试 我们已经完成了DateTime委托中的类 以便DateTime Now可以在单元测试中被覆盖 public static class SystemTime region Static Fields public stati