在 XUnit 中使用依赖注入

Intro

之前写过一篇 xunit 的依赖注入相关的文章,但是实际使用起来不是那么方便

今天介绍一个基于xunit和微软依赖注入框架的“真正”的依赖注入使用方式 ——— Xunit.DependencyInjection, 来自大师的作品,让你在测试代码里使用依赖注入像 asp.net core 一样轻松

使用一览

包引用

在 xunit 测试项目里添加对 Xunit.DependencyInjection 的引用

dotnet add package Xunit.DependencyInjection

新建自己的 Startup

需要实现自己的一个 Startup ,在 Startup 里进行服务注册和初始化

// 这里需要指定一个 assembly attribute 用来让 xunit 寻找测试入口,
// TestFramework 第一个参数是 Startup 类的 FullName(包含命名空间),第二个参数是测试项目的程序集名称
[assembly: TestFramework("XUnitDependencyInjectionSample.Startup", "XUnitDependencyInjectionSample")] namespace XUnitDependencyInjectionSample
{
// Startup 需要继承于 DependencyInjectionTestFramework
public class Startup : DependencyInjectionTestFramework
{
public Startup(IMessageSink messageSink) : base(messageSink)
{
} // 重写 CreateHostBuilder 这个方法,在这里进行配置注册和服务注册
protected override IHostBuilder CreateHostBuilder(AssemblyName assemblyName)
{
var hostBuilder = base.CreateHostBuilder(assemblyName);
hostBuilder
// 注册配置
.ConfigureAppConfiguration(builder =>
{
builder
.AddInMemoryCollection(new Dictionary<string, string>()
{
{"UserName", "Alice"}
})
.AddJsonFile("appsettings.json")
;
})
// 注册自定义服务
.ConfigureServices((context, services) =>
{
services.AddSingleton<IIdGenerator, GuidIdGenerator>();
if (context.Configuration.GetAppSetting<bool>("XxxEnabled"))
{
services.AddSingleton<IUserIdProvider, EnvironmentUserIdProvider>();
}
})
; return hostBuilder;
} protected override void Configure(IServiceProvider provider)
{
// 有一些测试数据需要初始化可以放在这里
}
}
}

CreateHostBuilder 其实就是 asp.net core 里的创建一个 HostBuilder ,注册配置/服务和 asp.net core 里一模一样,有数据或配置需要在项目启动时初始化的,可以放在 Configure 方法做,有点类似于 asp.net core 里 Startup 中的 Configure 方法,只是这里我们不需要配置 asp.net core 的请求管道

开始在测试代码里使用依赖注入吧

上面的 Startup 配置好以后就可以在测试代码里尽情使用依赖注入了,来看下面的两个示例:

首先我们可以测试一下内置的服务,就拿 IConfiguration 来测试吧

再来测试一下我们自定义注册的服务:

IOutputHelper 是 xunit 提供的,可以在执行测试的时候输出一段文本(使用 Console.WriteLine 是看不到输出的哦)

来看一下测试结果

实现原理

Xunit.DependencyInjection 是一个开源项目,你可以在 Github 上获取到源码 https://github.com/pengweiqhca/Xunit.DependencyInjection

Xunit.DependencyInjection 重写了一套基于 Microsoft.Extensions.DependencyInjection TestFramework

使得测试执行可以支持依赖注入的方式,

在构建测试类时可以从注册的服务中获取构造器所需要的参数

在构建测试方法的时候也可以通过指定 FromServices 来从注册的服务中获取对应的服务从而实现方法参数的注入

重写的 xunit 的类如下

从 5.0 版本开始直接依赖于 Microsoft.Extensions.Hosting,使用通用主机来构建依赖注入测试框架,

这样使得我们更方便集成 Configuration ,更像 asp.net core 的配置,更简洁

More

大师写的项目真心不错,但是大师太低调了,写的很多很实用的项目,携程的阿波罗的 dotnetcore 支持就是大师一直在维护,,大家快去 Github follow 他吧

大师最近在写一个 NetCache 的开源项目,一个缓存框架,感兴趣的可以去看一下,给大师提点 feature ,

项目地址:https://github.com/pengweiqhca/NetCache

Reference

在 XUnit 中使用依赖注入的更多相关文章

  1. 更优雅的在 Xunit 中使用依赖注入

    Xunit.DependencyInjection 7.0 发布了 Intro 上次我们已经介绍过一次大师的 Xunit.DependencyInjection https://www.cnblogs ...

  2. 在 xunit 测试项目中使用依赖注入

    在 xunit 测试项目中使用依赖注入 Intro 之前写过几篇 xunit 依赖注入的文章,今天这篇文章将结合我在 .NET Conf 上的分享,更加系统的分享一下在测试中的应用案例. 之所以想分享 ...

  3. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  4. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  5. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

  6. 在.NET Core控制台程序中使用依赖注入

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

  7. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  8. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  9. ASP.NET Core中的依赖注入(3): 服务的注册与提供

    在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...

随机推荐

  1. Java实现 蓝桥杯VIP 算法提高 3-2求存款

    算法提高 3-2求存款 时间限制:1.0s 内存限制:256.0MB 问题描述 见计算机程序设计基础(乔林)P50第5题. 接受两个数,一个是用户一年期定期存款金额,一个是按照百分比格式表示的利率,计 ...

  2. Java实现蓝桥杯正则切分

    java中提供了对正则表达式的支持. 有的时候,恰当地使用正则,可以让我们的工作事半功倍! 如下代码用来检验一个四则运算式中数据项的数目,请填写划线部分缺少的代码. 注意:只填写缺少代码,不要写任何多 ...

  3. java实现求二十一位水仙花数(21位水仙花数)

    一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数. 例如: 当N=3时,153就满足条件,因为 1^3 + 5^3 + 3^3 = 153,这样的数字也被称为水 ...

  4. Linux 文件特殊权限-SetGID

    SUID只针对二进制可执行文件,而SGID可以针对二进制文件,这时它和SUID非常类似,命令执行在执行程序的时候,组身份变换为该文件的属组,最常见的locate命令,普通用户也可以搜索文件目录,它也可 ...

  5. (五)SQLMap工具检测SQL注入漏洞、获取数据库中的数据

    目录结构 一.判断被测url的参数是否存在注入点 二.获取数据库系统的所有数据库名称(暴库) 三.获取Web应用当前所连接的数据库 四.获取Web应用当前所操作的DBMS用户 五.列出数据库中的所有用 ...

  6. ubuntu下Vivado launch SDK后,SDK无菜单栏解决办法

    最近在调Xilinx的ZYNQ 7015,按照教程从Vivado中Launch SDK后遇到了个问题,SDK的菜单栏消失了,真的没了,我的环境是ubuntu 16.4.百度好久都没有人遇到该问题,经过 ...

  7. Hadoop之hadoop fs和hdfs dfs、hdfs fs三者区别

      适用范围 案例 备注 小记 hadoop fs 使用范围最广,对象:可任何对象       hadoop dfs 只HDFS文件系统相关       hdfs fs 只HDFS文件系统相关(包括与 ...

  8. 温故知新-多线程-深入刨析volatile关键词

    文章目录 摘要 volatile的作用 volatile如何解决线程可见? CPU Cache CPU Cache & 主内存 缓存一致性协议 volatile如何解决指令重排序? volat ...

  9. iOS-自定义Model转场动画-仿酷我音乐播放器效果

    周末,闲来无事,仿写了酷我音乐播放器效果: 效果图如下: 实现思路: 1.实现手势处理视图旋转 2.自定义Model动画: 1.手势是利用了一个UIPanGestureRecognizer手势: 注意 ...

  10. 在MyEclipse中设置jdk

    在MyEclipse中设置jdk的三处地方:1 选中项目右键菜单properties -->java Compiler 2 windows菜单中Preferences-->myeclips ...