我有一个用NUnit编写的特殊测试,它在Visual Studio Test Explorer中传递但在NUnit gui中运行时没有通过。单元测试使用 Interceptor 类来交换两个方法,这样我就可以使用第二种方法作为第一种方法,用于被测单元中的第一种方法。这是通过C#unsafe(非托管)代码完成的:
public static void Inject( MethodInfo replacedMethod, MethodInfo injectionMethod )
{
RuntimeHelpers.PrepareMethod( replacedMethod.MethodHandle );
RuntimeHelpers.PrepareMethod( injectionMethod.MethodHandle );
unsafe {
if( IntPtr.Size == 4 ) {
int* inj = (int*) replacedMethod.MethodHandle.Value.ToPointer() + 2;
int* tar = (int*) injectionMethod.MethodHandle.Value.ToPointer() + 2;
if( System.Diagnostics.Debugger.IsAttached ) {
//Version x86 Debug
byte* injInst = (byte*) *inj;
byte* tarInst = (byte*) *tar;
int* injSrc = (int*) (injInst + 1);
int* tarSrc = (int*) (tarInst + 1);
Replaced = (((int) tarInst + 5) + *tarSrc) - ((int) injInst + 5);
*tarSrc = (((int) injInst + 5) + *injSrc) - ((int) tarInst + 5);
*injSrc = Replaced;
}
else {
//Version x86 Release
Replaced = *tar;
*tar = *inj;
*inj = Replaced;
}
}
}
}
我从单元测试中调用Inject方法:
public static void SecondMethod( double[] e, out double var1, out double var2, out double var3 )
{
var1 = new Double();
var2= new Double();
var3 = new Double();
var1 = 0.0;
var2 = 0.0;
var3 = 0.0;
}
[Test]
public void Utilites_Tanks_ApproximateApogee_ReturnsTrue(){
double val = 10;
double[] ecr = { 1.2, 3.4, 5.6, 4.5, 6.7, 8.9 };
MethodInfo x = typeof( FirstMethodClass ).GetMethods().Single(m => m.Name == "FirstMethod" && m.GetParameters().Length == 4);
MethodInfo z = typeof( TestClass ).GetMethod( "SecondMethod" );
Interceptor.Inject( x,z );
bool stageValue = UnitUnderTestMethodClass.Method( ecr, val, out double[] apogeeInfo2 );
Assert.That( stageValue, Is.True );
}
此测试按计划进行;它在Visual Studio测试资源管理器中传递,它确实显示在NUnit gui中。挂断的是它在NUnit gui中运行时没有通过。我已经在NUnit gui版本2.6中运行了测试。#和3.#具有相同的结果。还有另一个我写的测试,它接近同一个东西并且它通过了。该测试是交换没有参数传递的方法,因此GetMethod部分在Interceptor中完成,与此测试不同。
我想知道NUnit gui是否与不安全(非托管)代码配合得不好。我在NUnit gui中引用了正确的构建,所以我不相信这是问题所在。
感谢名单