Token导航 LogoToken导航

Agent Skill · 待分类

dotnet-testing-datetime-testing-timeprovider(dotnet 测试 datetime 测试 timeprovider)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

dotnet-testing-datetime-testing-timeprovider 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 5,043。

总安装 629周安装 27GitHub Stars 24下载 220核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:dotnet-testing-datetime-testing-timeprovider(dotnet 测试 datetime 测试 timeprovider)
来源仓库:https://github.com/kevintsengtw/dotnet-testing-agent-skills
仓库路径:skills/dotnet-testing-datetime-testing-timeprovider
安装命令:
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-datetime-testing-timeprovider
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-datetime-testing-timeprovider

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

dotnet-testing-datetime-testing-timeprovider 使用时间抽象层 TimeProvider 替代静态 DateTime.Now。解决时间相关逻辑难以预测与复现的测试难题,提升确定性。支持冻结时间、快进时间或切换不同时区进行测试场景模拟。

需注入 ITimeProvider 并通过 Microsoft.Extensions.TimeProvider.Testing 包实现替换。重构时应优先提取时间获取点为虚方法,保持向后兼容旧调用方。

来源仓库内路径:skills/dotnet-testing-datetime-testing-timeprovider

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --ski…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

dotnet-testing-datetime-testing-timeprovider 怎么安装?

在终端执行 npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

dotnet-testing-datetime-testing-timeprovider 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

dotnet-testing-datetime-testing-timeprovider 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

dotnet-testing-datetime-testing-timeprovider 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

dotnet-testing-datetime-testing-timeprovider 用的人多吗?

公开数据是累计安装 629 次,近一周安装 27 次,下载 220 次,GitHub 24 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

dotnet-testing-datetime-testing-timeprovider 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
dotnet-testing-datetime-testing-timeprovider

dotnet 测试 datetime 测试 timeprovider · 本页

62924需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

DateTime 與時間相依性測試指南

核心原則

原則一:時間抽象化 - 以 TimeProvider 取代 DateTime

傳統問題程式碼:

// ❌ 無法測試 - 直接使用靜態時間
public class OrderService
{
    public bool CanPlaceOrder()
    {
        var now = DateTime.Now;
        return now.Hour >= 9 && now.Hour < 17;
    }
}

可測試的重構:

// ✅ 可測試 - 透過依賴注入接收 TimeProvider
public class OrderService
{
    private readonly TimeProvider _timeProvider;

    public OrderService(TimeProvider timeProvider)
    {
        _timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
    }

    public bool CanPlaceOrder()
    {
        var now = _timeProvider.GetLocalNow();
        return now.Hour >= 9 && now.Hour < 17;
    }
}

依賴注入設定:

// Program.cs - 生產環境使用系統時間
services.AddSingleton(TimeProvider.System);
services.AddScoped<OrderService>();

原則二:FakeTimeProvider 控制測試時間

FakeTimeProvider 提供完整的時間控制能力:

方法用途使用時機
SetUtcNow(DateTimeOffset)設定 UTC 時間需要精確 UTC 時間時
SetLocalTimeZone(TimeZoneInfo)設定本地時區測試時區相關邏輯
Advance(TimeSpan)時間快轉測試過期、延遲邏輯
GetUtcNow()取得 UTC 時間讀取當前模擬時間
GetLocalNow()取得本地時間讀取本地模擬時間

建議擴充方法:

public static class FakeTimeProviderExtensions
{
    /// <summary>
    /// 設定 FakeTimeProvider 的本地時間
    /// </summary>
    public static void SetLocalNow(this FakeTimeProvider fakeTimeProvider, DateTime localDateTime)
    {
        fakeTimeProvider.SetLocalTimeZone(TimeZoneInfo.Local);
        var utcTime = TimeZoneInfo.ConvertTimeToUtc(localDateTime, TimeZoneInfo.Local);
        fakeTimeProvider.SetUtcNow(utcTime);
    }
}

原則三:每個測試使用獨立的時間環境

// ✅ 正確:每個測試獨立建立 FakeTimeProvider
public class OrderServiceTests
{
    [Fact]
    public void CanPlaceOrder_在營業時間內_應回傳True()
    {
        // Arrange - 獨立實例
        var fakeTimeProvider = new FakeTimeProvider();
        fakeTimeProvider.SetLocalNow(new DateTime(2024, 3, 15, 14, 0, 0));
        var sut = new OrderService(fakeTimeProvider);

        // Act
        var result = sut.CanPlaceOrder();

        // Assert
        result.Should().BeTrue();
    }
}

// ❌ 避免:多個測試共用靜態實例
public class BadTestClass
{
    private static readonly FakeTimeProvider SharedProvider = new(); // 會互相干擾
}

進階時間控制技術

時間凍結

當需要驗證多個操作發生在「同一時間點」:

[Fact]
public void ProcessBatch_在固定時間點_應產生相同時間戳()
{
    var fakeTimeProvider = new FakeTimeProvider();
    var fixedTime = new DateTime(2024, 12, 25, 10, 30, 0);
    fakeTimeProvider.SetLocalNow(fixedTime);

    var processor = new BatchProcessor(fakeTimeProvider);

    var result1 = processor.ProcessItem("Item1");
    var result2 = processor.ProcessItem("Item2");

    // 時間被凍結,兩次操作的時間戳相同
    result1.Timestamp.Should().Be(result2.Timestamp);
}

時間快轉 (Advance)

測試快取過期、Token 失效等時間敏感邏輯:

[Fact]
public void Cache_經過過期時間_應清除項目()
{
    var fakeTimeProvider = new FakeTimeProvider();
    fakeTimeProvider.SetLocalNow(new DateTime(2024, 3, 15, 10, 0, 0));

    var cache = new TimedCache(fakeTimeProvider, TimeSpan.FromMinutes(5));
    cache.Set("key", "value");

    // 3 分鐘後 - 尚未過期
    fakeTimeProvider.Advance(TimeSpan.FromMinutes(3));
    cache.Get("key").Should().Be("value");

    // 再 3 分鐘後(共 6 分鐘)- 已過期
    fakeTimeProvider.Advance(TimeSpan.FromMinutes(3));
    cache.Get("key").Should().BeNull();
}
重要:Advance() 是非阻塞的,瞬間完成時間跳躍,不會真正等待。

時間倒轉

測試歷史資料處理或重播場景:

[Fact]
public void HistoricalDataProcessor_回到過去時間_應正確處理()
{
    var fakeTimeProvider = new FakeTimeProvider();
    var historicalTime = new DateTime(2020, 1, 15, 9, 0, 0);
    fakeTimeProvider.SetLocalNow(historicalTime);

    var processor = new HistoricalDataProcessor(fakeTimeProvider);
    var result = processor.ProcessDataForDate(historicalTime.Date);

    result.ProcessedAt.Should().Be(historicalTime);
}

實戰測試模式

模式一:參數化邊界測試

[Theory]
[InlineData(8, false)]   // 上午 8 點 - 營業時間前
[InlineData(9, true)]    // 上午 9 點 - 剛開始營業
[InlineData(12, true)]   // 中午 12 點 - 營業時間內
[InlineData(16, true)]   // 下午 4 點 - 營業時間內
[InlineData(17, false)]  // 下午 5 點 - 剛結束營業
[InlineData(18, false)]  // 下午 6 點 - 營業時間後
public void CanPlaceOrder_不同時間點_應回傳正確結果(int hour, bool expected)
{
    var fakeTimeProvider = new FakeTimeProvider();
    fakeTimeProvider.SetLocalNow(new DateTime(2024, 3, 15, hour, 0, 0));

    var sut = new OrderService(fakeTimeProvider);

    sut.CanPlaceOrder().Should().Be(expected);
}

模式二:交易時間窗口測試

[Theory]
[InlineData("09:30:00", true)]   // 上午交易時間
[InlineData("12:00:00", false)]  // 中午休息
[InlineData("14:30:00", true)]   // 下午交易時間
[InlineData("15:30:00", false)]  // 交易結束後
public void IsInTradingHours_不同時間_應回傳正確結果(string timeStr, bool expected)
{
    var fakeTimeProvider = new FakeTimeProvider();
    var testTime = DateTime.Today.Add(TimeSpan.Parse(timeStr));
    fakeTimeProvider.SetLocalNow(testTime);

    var sut = new TradingService(fakeTimeProvider);

    sut.IsInTradingHours().Should().Be(expected);
}

模式三:排程觸發邏輯測試

[Theory]
[InlineData("2024-03-15 14:30:00", "2024-03-15 14:00:00", true)]   // 已到執行時間
[InlineData("2024-03-15 13:30:00", "2024-03-15 14:00:00", false)]  // 尚未到時間
public void ShouldExecuteJob_根據時間判斷_應回傳正確結果(
    string currentTimeStr, string scheduledTimeStr, bool expected)
{
    var fakeTimeProvider = new FakeTimeProvider();
    fakeTimeProvider.SetLocalNow(DateTime.Parse(currentTimeStr));

    var schedule = new JobSchedule { NextExecutionTime = DateTime.Parse(scheduledTimeStr) };
    var sut = new ScheduleService(fakeTimeProvider);

    sut.ShouldExecuteJob(schedule).Should().Be(expected);
}

AutoFixture 整合

FakeTimeProviderCustomization

public class FakeTimeProviderCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Register(() => new FakeTimeProvider());
    }
}

AutoDataWithCustomization 屬性

public class AutoDataWithCustomizationAttribute : AutoDataAttribute
{
    public AutoDataWithCustomizationAttribute() : base(CreateFixture)
    {
    }

    private static IFixture CreateFixture()
    {
        return new Fixture()
            .Customize(new AutoNSubstituteCustomization())
            .Customize(new FakeTimeProviderCustomization());
    }
}

使用 Matching.DirectBaseType

[Theory]
[AutoDataWithCustomization]
public void GetTimeBasedDiscount_週五_應回傳九折優惠(
    [Frozen(Matching.DirectBaseType)] FakeTimeProvider fakeTimeProvider,
    OrderService sut)
{
    // Matching.DirectBaseType 讓 AutoFixture 知道:
    // 當需要 TimeProvider(基底類型)時,使用 FakeTimeProvider(衍生類型)

    var fridayTime = new DateTime(2024, 3, 15, 14, 0, 0); // 週五
    fakeTimeProvider.SetLocalNow(fridayTime);

    sut.GetTimeBasedDiscount().Should().Be("週五快樂:九折優惠");
}
關鍵:必須使用 [Frozen(Matching.DirectBaseType)],否則 AutoFixture 無法正確將 FakeTimeProvider 注入到需要 TimeProvider 的建構式中。

最佳實踐檢查清單

程式碼設計

  • 所有時間相依類別透過建構式接收 TimeProvider
  • 使用 _timeProvider.GetLocalNow() 取代 DateTime.Now
  • 使用 _timeProvider.GetUtcNow() 取代 DateTime.UtcNow
  • DI 容器註冊 TimeProvider.System 作為生產環境實作

測試設計

  • 每個測試方法使用獨立的 FakeTimeProvider 實例
  • 使用 SetLocalNow() 擴充方法簡化時間設定
  • 使用 Advance() 測試時間敏感邏輯(快取、過期、延遲)
  • 測試涵蓋邊界條件(開始時間、結束時間、臨界點)

進階考量

  • FakeTimeProvider 是執行緒安全的,可用於並行測試
  • 使用 IDisposable 模式正確釋放 FakeTimeProvider
  • 時區測試使用 SetLocalTimeZone() 明確設定時區

輸出格式

  • 產生使用 TimeProvider 抽象的服務類別
  • 產生使用 FakeTimeProvider 的測試類別
  • 包含時間凍結、快轉、時區轉換測試範例
  • 提供.csproj 套件參考(Microsoft.Bcl.TimeProvider)

參考資源

原始文章

本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:

  • Day 16 - 測試日期與時間:Microsoft.Bcl.TimeProvider 取代 DateTime

- 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10375821 - 範例程式碼:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day16

官方文件

相關技能

  • autofixture-basics - AutoFixture 自動測試資料生成
  • nsubstitute-mocking - 測試替身與模擬
  • autodata-xunit-integration - xUnit 與 AutoFixture 的 AutoData 整合

平台分布

Claude Code

30.25%
按下载量换算67

Gemini CLI

23.63%
按下载量换算52

Antigravity

16.09%
按下载量换算35

OpenCode

12.3%
按下载量换算27

windsurf

8.13%
按下载量换算18

github-copilot

3.68%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills