Как поместить новый List<int> {1} в NUNIT TestCase?
У меня есть метод:
public static int Add(List<int> numbers)
{
if (numbers == null || numbers.Count == 0)
return 0;
if (numbers.Count == 1)
return numbers[0];
throw new NotImplementedException();
}
Вот мой тест против этого, но это не нравится new List<int> {1}
в TestCase:
[TestCase(new List<int>{1}, 1)]
public void Add_WithOneNumber_ReturnsNumber(List<int> numbers)
{
var result = CalculatorLibrary.CalculatorFunctions.Add(numbers);
Assert.AreEqual(1, result);
}
Это дает мне ошибку:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
Должен ли я сделать это так:
[Test]
public void Add_WithOneNumber_ReturnsNumber()
{
var result = CalculatorLibrary.CalculatorFunctions.Add(new List<int>{7});
Assert.AreEqual(7, result);
var result2 = CalculatorLibrary.CalculatorFunctions.Add(new List<int> {3});
Assert.AreEqual(4,result2);
}
7 ответов
Существует один вариант использования атрибута TestCaseSource. Здесь я приведу тест без утверждения с двумя случаями, просто чтобы посмотреть, как он работает:
[TestFixture]
public class TestClass
{
private object[] _sourceLists = {new object[] {new List<int> {1}}, //case 1
new object[] {new List<int> {1, 2}} //case 2
};
[Test, TestCaseSource("_sourceLists")]
public void Test(List<int> list)
{
foreach (var item in list)
Console.WriteLine(item);
}
}
Во всяком случае, я должен упомянуть, что это не самое очевидное решение, и я бы предпочел аккуратно организованные светильники, игнорируя тот факт, что они более многословны
Мое решение проще, я просто использую params
, Я надеюсь, что это работает для вас!
[TestCase(1, 1)]
[TestCase(10, 5, 1, 4)]
[TestCase(25, 3, 5, 5, 12)]
public void Linq_Add_ShouldSumAllTheNumbers(int expected, params int[] numbers)
{
var result = CalculatorLibrary.CalculatorFunctions.Add(numbers);
Assert.AreEqual(expected, result);
}
Улучшение кода для ответа @Yurii Hohan:
private static readonly object[] _Data =
{
new object[] {new List<int> {0}, "test"},
new object[] {new List<int> {0, 5}, "test this"},
};
[Test, TestCaseSource(nameof(_Data))]
Надеюсь, это поможет.
Вы можете использовать это:
[TestCase (new [] {1,2,3})]
public void Add_WithOneNumber_ReturnsNumber (int [] numbers)
Я часто использую строки и синтаксический анализ, так как он хорошо отрисовывается в тестовом раннере. Образец:
[TestCase("1, 2")]
[TestCase("1, 2, 3")]
public void WithStrings(string listString)
{
var list = listString.Split(',')
.Select(int.Parse)
.ToList();
Console.WriteLine(string.Join(",", list));
}
Похоже на это у бегуна Решарпера:
Использовать массив в качестве параметра new [] {1}
и преобразовать его в список внутри метода теста result.ToList()
, Это необходимо using System.Linq;
,
[TestCase(new [] {1}, 1)]
[TestCase(new [] {2}, 2)]
[TestCase(new [] {1000}, 1000)]
public void Add_WithOneNumber_ReturnsNumber(int[] numbers)
{
var result = CalculatorLibrary.CalculatorFunctions.Add(numbers);
Assert.AreEqual(1, result.ToList());
}
Вы не можете использовать объекты только константы времени компиляции в атрибутах данных. Чтобы не использовать рефлексию, которую я нахожу крайне нечитаемой и совсем не подходящей для теста, который предназначен для формального описания поведения как можно более четко, вот что я делаю:
[Test]
public void Test_Case_One()
{
AssertCurrency(INPUT, EXPECTED);
}
[Test]
public void Test_Case_Two()
{
AssertCurrency(INPUT, EXPECTED);
}
private void AssertScenario(int input, int expected)
{
Assert.AreEqual(expected, input);
}
Это еще несколько строк, но это только потому, что я хочу получить четкие результаты теста. Вы могли бы так же легко поместить их в один [Тест], если вы ищете что-то более краткое.
Просто создайте список внутри метода, как здесь:
public void Add_WithOneNumber_ReturnsNumber()
{
var result = CalculatorLibrary.CalculatorFunctions.Add(new List<int>{1});
Assert.AreEqual(1, result);
}