Я создал теорию NUnit, чтобы помочь мне протестировать некоторый код. Фактический тестируемый код не так важен для этого вопроса, как данные, которые я использую для его тестирования. А именно, часы и минуты времени в 24-часовом формате.
Я написал свое приспособление таким образом, чтобы извлечь выгоду из функций и соответствовать ограничениям функции NUnit 2.6 Theory. В частности, я чувствовал, что мне нужно создать такие классы, как Hour и Minute, чтобы обойти функцию, согласно которой точки данных сопоставляются с аргументами по точному типу.
[TestFixture]
public class TimeWindowParserTheoryFixture
{
public class Hour
{
public int Value;
}
public class Minute
{
public int Value;
public string AsString { get { return Value.ToString("00"); } }
}
[Datapoints]
public IEnumerable<Hour> Hours
{
get
{
return Enumerable
.Range(0, 25)
.Select(v => new Hour() { Value = v })
.Union(Enumerable.Repeat((Hour)null, 1));
}
}
[Datapoints]
public IEnumerable<Minute> Minutes
{
get
{
return Enumerable
.Range(0, 60)
.Select(v => new Minute() { Value = v })
.Union(Enumerable.Repeat((Minute)null, 1));
}
}
[Datapoints]
public IEnumerable<string> Separators
{
get { return new[] { " ", "-" }; }
}
[Theory]
public void ValidHours(Hour startHour,
Minute startMinute,
Hour endHour,
Minute endMinute,
string separator)
{
Assume.That(startHour != null);
Assume.That(endHour != null);
var parser = new TimeWindowParser();
var startMinutesString = String.Format("{0}{1}", startMinute == null ? "" : ":", startMinute == null ? "" : startMinute.AsString);
var endMinutesString = String.Format("{0}{1}", endMinute == null ? "" : ":", endMinute == null ? "" : endMinute.AsString);
var pattern = String.Format("{0}{1}{2}{3}{4}{5}{6}", startHour, startMinutesString, "", separator, endHour, endMinutesString, "");
//Console.WriteLine(pattern);
var result = parser.Parse(pattern);
Assert.That(result, Is.Not.Null);
Assert.That(result.Start, Is.EqualTo(startHour));
Assert.That(result.End, Is.EqualTo(endHour));
}
}
Я обнаружил, что размер набора данных, созданный во время комбинаторной логики NUnit по умолчанию, приводит к такому большому набору, что мне не хватает памяти. Не похоже, что способ, которым я настроил свой тест и данные, должен быть проблемой, но, поскольку это очевидно, поэтому я прошу совета о том, как по-другому думать об этой проблеме. Вот трассировка стека OutOfMemoryException, которую я получаю.
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)
at System.Text.StringBuilder.Append(Char* value, Int32 valueCount)
at System.Text.StringBuilder.AppendHelper(String value)
at System.Text.StringBuilder.Append(String value)
at NUnit.Core.MethodHelper.GetDisplayName(MethodInfo method, Object[] arglist)
at NUnit.Core.Builders.NUnitTestCaseBuilder.BuildSingleTestMethod(MethodInfo method, Test parentSuite, ParameterSet parms)
Это исключение само по себе является странным, так как кажется, что оно генерируется просто при попытке получить имя метода Test (см. GetDisplayName). Я не уверен, является ли это ошибкой (известной или нет). Кстати, я получаю очень похожее исключение OOM, когда переписываю это приспособление, используя менее экспериментальные атрибуты Range и Value, используемые в параметризованных тестах.