Использование атрибута TestCase с двумерным массивом
Я использую NUnit и пытаюсь реализовать тесты для следующего метода: он должен принимать два целых числа и возвращает двумерный массив. Итак, заголовок моего теста выглядит так:
[TestCase(5, 1, new int[,]{{1}, {2}, {3}, {4}, {5}})]
public void MyTestMethod(int a, int b, int[][] r)
Во время компиляции я получил следующую ошибку:
Ошибка CS0182: аргумент атрибута должен быть выражением константы, выражением typeof или выражением создания массива типа параметра атрибута (CS0182)
Я знаю, что это можно сделать с помощью TestCaseSource
для ссылки на массивы объектов, таких как ответы на следующие вопросы:
- Как поместить новый Список {1} в NUNIT TestCase?
- Последовательный атрибут NUnit с массивами в значениях
который дает код как:
private object[][] combination_tests = new [] {
new object[] {5, 1, new [,]{{1}, {2}, {3}, {4}, {5}}},
};
[Test]
[TestCaseSource("combination_tests")]
public void MyTestMethod(int a, int b, int[,] r)
но у меня все еще есть вопрос: возможно ли это сделать, используя только TestCase
атрибут?
2 ответа
Вам абсолютно необходимо иметь одинаковую подпись для вашего метода, т.е.
public void MyTestMethod(int a, int b, int[][] r)
{
// elided
}
В зависимости от вашей ситуации, у вас есть два варианта, оба из которых используют [TestCase]
атрибут, как вы сказали, что вы хотели в вопросе:
Можно ли это сделать, используя только
TestCase
атрибут?
Я предпочитаю первый вариант, так как он кажется более лаконичным, но оба подойдут под ваши нужды.
Вариант 1: если нет необходимости хранить одну и ту же подпись
Вы можете немного изменить сигнатуру, чтобы вместо массива (не константы времени компиляции) вы передавали строку ( которая является константой времени компиляции), которую можно использовать для получения массива, например:
private static int[][] getArrayForMyTestMethod(string key)
{
// logic to get from key to int[][]
}
[TestCase(5, 1, "dataset1")]
public void MyTestMethod(int a, int b, string rKey)
{
int[][] r = getArrayForMyTestMethod(rKey);
// elided
}
Вариант 2: если необходимо сохранить одинаковую подпись
Если необходимо сохранить одну и ту же сигнатуру для метода, у вас может быть метод-обертка, который делает то же самое, что и вариант 1, т.е.
private static int[][] getArrayForMyTestMethod(string key)
{
// logic to get from key to int[][]
}
[TestCase(5, 1, "dataset1")]
public void MyTestMethodWrapper(int a, int b, string rKey)
{
int[][] r = getArrayForMyTestMethod(rKey);
MyTestMethod(a, b, r);
}
public void MyTestMethod(int a, int b, int[][] r)
{
// elided
}
Очевидно, вы можете использовать любой тип, который может быть константой времени компиляции вместо string
в зависимости от того, как устроены ваши тестовые примеры, но я предложил string
потому что таким образом вы сможете дать имя своему тестовому сценарию в NUnit.
В противном случае ваша альтернатива заключается в использовании [TestCaseSource]
как вы упомянули в своем вопросе.
Вы можете использовать объект testcasedata для передачи результатов в
public IEnumerable<TestCaseData> combination_tests()
{
yield return new TestCaseData(5,1,new int[,] {{1}, {2}, {3}, {4}, {5}});
}
[Test]
[TestCaseSource("combination_tests")]
public void test(int a, int b, int[,] r)
{
Console.WriteLine(r[0,0] & r[1,0]);
}
Вы также можете установить категорию теста и имя теста для каждого элемента testCaseData, используя.SetName("xxx") или.SetCategory("xxx"), что может быть удобно для организации тестов.