如何让.NET 8测试项目调用自定义的Random.NextInt64实现?
问题描述
我有一个面向多目标框架的类库,目标框架包含.NET 8和.NET Standard 2.1。由于旧框架缺少部分函数,我为其实现了自定义版本,示例代码如下:
public static class RandomExtensions { #if NETSTANDARD2_1_OR_GREATER public static long NextInt64(this Random random) => // 我的自定义实现 #endif }
我有一个面向.NET 8的xUnit测试项目,测试代码如下:
// 暂时忽略这是个简单测试... public class RandomExtensionsTests { [Fact] public void NextInt64() { var random = new Random(); var value = random.NextInt64(); Assert.InRange(value, 0, long.MaxValue - 1); } }
运行测试时,代码调用的是.NET 8原生的NextInt64方法,我想让它调用我的自定义实现。
我原本考虑让测试项目与类库使用相同的目标框架,但测试项目无法面向.NET Standard(因为它不是运行平台)。尝试面向.NET Core App 2.1时,引用类库出现警告Project xxx is not compatible with netcoreapp2.1,不知道该怎么做了。
解决方案
这里有几种可行的方式来测试你的自定义NextInt64实现:
1. 自定义编译符号,强制测试项目启用自定义实现
调整类库的条件编译逻辑,给测试项目单独添加编译符号,让它优先使用你的自定义方法:
- 修改类库代码,新增自定义编译符号
USE_CUSTOM_NEXTINT64:
public static class RandomExtensions { #if NETSTANDARD2_1_OR_GREATER || USE_CUSTOM_NEXTINT64 public static long NextInt64(this Random random) => // 我的自定义实现 #endif }
- 打开测试项目属性,在「生成」选项卡的「条件编译符号」中添加
USE_CUSTOM_NEXTINT64。 - 编译测试项目时,会包含你的自定义方法,由于同命名空间下的扩展方法优先级高于系统类库的扩展,测试代码会自动调用你的实现。
2. 给测试项目设置多目标框架,兼容.NET Standard 2.1
.NET Core 3.1完全支持.NET Standard 2.1,且xUnit支持该运行时:
- 修改测试项目的
.csproj文件,设置多目标框架:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>net8.0;netcoreapp3.1</TargetFrameworks> <Nullable>enable</Nullable> </PropertyGroup> <!-- 其他依赖项配置 --> </Project>
- 切换到
netcoreapp3.1运行测试时,类库会编译为.NET Standard 2.1版本,自然会使用你的自定义NextInt64实现;而net8.0版本可用来验证原生方法的兼容性。
3. 通过反射强制调用自定义实现
如果不想修改项目配置,可以在测试代码中用反射直接调用你的扩展方法:
[Fact] public void NextInt64() { var random = new Random(); // 获取自定义扩展方法 var method = typeof(RandomExtensions).GetMethod(nameof(RandomExtensions.NextInt64), new[] { typeof(Random) }); var value = (long)method.Invoke(null, new[] { random }); Assert.InRange(value, 0, long.MaxValue - 1); }
这种方式无需修改类库代码,直接绕过方法解析逻辑,调用你的自定义实现。
内容的提问来源于stack exchange,提问作者CaseyHofland
相关产品推荐
相关产品推荐

