简体   繁体   English

如何调用具有多个参数的测试方法(NUnit)

[英]How to invoke test method with multiple parameters (NUnit)

My test method looks like this: 我的测试方法如下:

public static List<Something> Generator() {
return A.GenerateObjects();
}

[Test, TestCaseSource(nameof(Generator))]
    public void DoSomething(Something abc) {/*do something*/}

This code works very well and generates for each object in the list an unit case. 该代码效果很好,并为列表中的每个对象生成了一个单位格。

I want to include another parameter in the method like: 我想在方法中加入另一个参数,例如:

public void DoSomething(Something abc, string def)

I've tried it with these lines but it didn't work: 我已经用这些行尝试过了,但是没有用:

public static object[] Case =
    {
        new object[]
        {
            A.GenerateObjects(),
            someStrings
        }
    };

Maybe iterate the list with an loop function instead of invoking the method (GenerateObjects()) directly? 也许使用循环函数迭代列表,而不是直接调用方法(GenerateObjects())? I also don't understand how Nunit can recognize the objects from the list directly with only TestCaseSource(nameof(Generator)) 我也不明白Nunit如何仅使用TestCaseSource(nameof(Generator))直接从列表中识别对象

Thanks in advance! 提前致谢!

You can return an IEnumerable of TestCaseData like this: 您可以像这样返回一个TestCaseData的IEnumerable:

    public static IEnumerable<TestCaseData> Generator()
    {
        yield return new TestCaseData(new Something { SomeValue = "Hi" }, "Foo").SetName("FirstTest");
        yield return new TestCaseData(new Something { SomeValue = "Bye" }, "Bar").SetName("SecondTest");
    }

    [Test]
    [TestCaseSource(nameof(Generator))]
    public void DoSomething(Something abc, string def)
    {
        Console.WriteLine($"{abc.SomeValue},{def}");
    }

The SetName is optional, just if you want a more meaningful name than the default one it makes up. SetName是可选的,即使您想要比它组成的默认名称更有意义的名称。

I also don't understand how Nunit can recognize the objects from the list directly with only TestCaseSource(nameof(Generator)) 我也不明白Nunit如何仅使用TestCaseSource(nameof(Generator))直接从列表中识别对象

Nunit notices the TestCaseSource attribute on the test method, and then uses reflection to invoke the "Generator" method. Nunit注意到测试方法的TestCaseSource属性,然后使用反射来调用“ Generator”方法。 (Nameof is just sugar, the compiler substitutes it with the actual name when you build it). (Nameof只是糖,编译时会用实际名称替换它)。 Every TestCaseData object that is returned is another test case. 返回的每个TestCaseData对象都是另一个测试用例。 In my example above the tests will be run twice. 在上面的示例中,测试将运行两次。 FirstTest will have a Something instance where SomeValue is set to Hi and a def string of Foo. FirstTest将具有Something实例,其中SomeValue设置为Hi,并且定义字符串Foo。 SecondTest will have a Something instance where SomeValue is set to Bye and a def string of Bar. SecondTest将具有Something实例,其中SomeValue设置为Bye,并且带有def字符串Bar。

Your initial test takes a single argument of type Something . 您的初始测试采用的是Something类型的单个参数。 Apparently, A.GenerateObjects() returns some sort of IEnumerable of those objects - you don't show the detail. 显然, A.GenerateObjects()返回这些对象的某种IEnumerable-您不会显示详细信息。 Because the test is a single-argument method, that works. 因为测试是单参数方法,所以可以。 NUnit provides a special case for single argument methods, which is very forgiving and will accept arrays of objects or of the type that is required and generate the test cases for you itself. NUnit为单参数方法提供了一种特殊情况,这是非常宽容的,它将接受对象数组或所需类型的数组,并为您自己生成测试用例。

However, for multiple arguments, it's up to you to return a set of test cases from your method yourself. 但是,对于多个参数,由您自己从方法中返回一组测试用例。 As you probably know, the arguments to a method in C# are in the form of an object[] containing the arguments, like new object[] { aSomething, "astring" } . 您可能知道,C#中方法的参数采用object[]的形式,其中包含参数,例如new object[] { aSomething, "astring" }

Assuming that you have specific strings that need to be associated with each object, it's up to you to make that association. 假设您有需要与每个对象关联的特定字符串,则由您来进行关联。 How to do that depends on the details of what you are trying to do. 如何执行此操作取决于您要执行的操作的详细信息。

Do you have a list of strings, which you want to associate with the list of objects one for one? 您是否具有要与对象列表一对一关联的字符串列表? In that case, stop using [TestCaseSource] and use [ValueSource] or [Values] on each parameter of the test method. 在这种情况下,请停止使用[TestCaseSource]并在测试方法的每个参数上使用[ValueSource][Values] Apply [Sequential] to the method to cause NUnit to match up the objects and strings one for one. [Sequential]应用于该方法,以使NUnit一对一地匹配对象和字符串。 Here's an example... 这是一个例子

[Test, Sequential]
public void DoSomething(
    [ValueSource(typeof(A), nameof(GetObjects)] Something abc,
    [Values("string1", "string2", "string3")] string def)
{/*do something*/}

This is just one way to do it. 这只是做到这一点的一种方法。 I've had to do a bunch of guessing as to what data you have readily available and what you are trying to do. 对于您已经可以使用的数据以及正在尝试执行的操作,我不得不做大量的猜测。 If this approach doesn't work for you, please fill in the blanks a bit and I'll edit the answer. 如果这种方法对您不起作用,请填写一下空白处,然后我将编辑答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM