C# 有没有办法使用TestCase对Nunit中的对象运行不同操作方法的列表?
假设我有以下几点:C# 有没有办法使用TestCase对Nunit中的对象运行不同操作方法的列表?,c#,nunit,C#,Nunit,假设我有以下几点: [Test] // would like to parameterize the parameters in call AND the call itself public void Test() { var res1 = _sut.Method1(1); var res2 = _sut.Method2("test"); var res3 = _sit.Method3(3); Assert.That(res1,
[Test]
// would like to parameterize the parameters in call AND the call itself
public void Test()
{
var res1 = _sut.Method1(1);
var res2 = _sut.Method2("test");
var res3 = _sit.Method3(3);
Assert.That(res1, Is.Null);
Assert.That(res2, Is.Null);
Assert.That(res3, Is.Null);
}
我想使用TestCase/TestCaseSource属性(包括调用本身)参数化测试。由于测试的重复性,需要使用稍微不同的参数调用每个方法,但是我需要能够为每个不同的参数标记不同的调用。这在努尼特有可能吗?如果是这样,我该怎么做呢?好吧,NUnit中没有这样的内置机制。然而,如果一个测试中存在多个方法,我认为将它们分割成单独的测试是更好的做法 也就是说,如果您总是在同一个对象上调用这些方法(
\u sut
),您可以通过反射来实现这一点(如果您决定承担由此产生的开销)
例如,在TestCaseSource中添加一个字符串参数,并在测试方法中按如下方式调用它:
Type type = _sut.GetType();
MethodInfo methodInfo = type.GetMethod(methodName);
object result = methodInfo.Invoke(_sut, null);
[TestFixture]
public class TestClass
{
private Sut _sut;
public TestClass()
{
_sut = new Sut(...);
}
private IEnumerable<object> TestCases
{
get
{
var values = new object[,] { { 1, "test", 3 }, { 2, "hello", 0 }, ... };
for (var i = 0; i < values.GetLength(0); ++i)
{
yield return _sut.Method1((int)values[i,0]);
yield return _sut.Method2((string)values[i,1]);
yield return _sut.Method3((int)values[i,2]);
}
}
}
[TestCaseSource("TestCases")]
public void Test(object val)
{
Assert.That(val, Is.Null);
}
}
但是,当您想要参数化的每个方法采用不同数量的参数时,事情会很快变得复杂。调试和查看哪个测试失败也将更加困难。最好可以拆分这些测试。使用,您应该能够循环一个值数组并调用所需的方法,例如:
Type type = _sut.GetType();
MethodInfo methodInfo = type.GetMethod(methodName);
object result = methodInfo.Invoke(_sut, null);
[TestFixture]
public class TestClass
{
private Sut _sut;
public TestClass()
{
_sut = new Sut(...);
}
private IEnumerable<object> TestCases
{
get
{
var values = new object[,] { { 1, "test", 3 }, { 2, "hello", 0 }, ... };
for (var i = 0; i < values.GetLength(0); ++i)
{
yield return _sut.Method1((int)values[i,0]);
yield return _sut.Method2((string)values[i,1]);
yield return _sut.Method3((int)values[i,2]);
}
}
}
[TestCaseSource("TestCases")]
public void Test(object val)
{
Assert.That(val, Is.Null);
}
}
[TestFixture]
公共类TestClass
{
私立学校;
公共测试类()
{
_sut=新sut(…);
}
私有IEnumerable测试用例
{
得到
{
var值=新对象[,]{{1,“test”,3},{2,“hello”,0},…};
对于(var i=0;i
注意,\u sut
实例需要在TestClass
构造函数中实例化。仅在[SetUp]
或[TestFixtureSetUp]
方法中对其进行初始化是不够的
如果不同的方法调用需要不同的
\u sut
实例化,可以在构造函数中创建sut
实例的集合,并访问TestCases
getter的for
循环中的相关sut
项。或者,您甚至可以在getter中的所有Sut
项上循环…Hi。我知道使用MbUnit很容易做到这一点。。。使用NUnit,我认为您可以使用DB并将值存储在此DB中,然后使用datasourceInteresting建议对测试进行参数化,但是我得到“无法将表达式类型“lambda expression”转换为生成类型Tuple…我已经更新了示例,但我将更深入地研究代码。我会尽快回来。我第一次做得太过火了:-)更新后的示例怎么样?现在一切都编译好了,有什么变化?新问题是,TestCases属性中的_sut为null。我在fixture的Init()中“新建”了_sut。也许这太晚了?…我不知道这里执行的确切顺序,但我尝试在TestClass
构造函数中初始化\u sut
,然后\u sut
在TestCases
属性中充分初始化。我会更新答案以确保完整性。是的,我觉得虽然不错,但这太过分了。我通过createhelper方法减少了每个测试中的行数,这样重复测试就不会太糟糕了。然而,我确实认为这种东西在测试状态机等方面是有用的。。。