Могу ли я запускать варианты моего тестового класса XUnit?C#

Место общения программистов C#
Ответить
Anonymous
 Могу ли я запускать варианты моего тестового класса XUnit?

Сообщение Anonymous »

При добавлении флага функции в какой-либо код мне нужен способ выполнения существующего кода как с примененным флагом, так и без него, чтобы гарантировать, что его включение/выключение не нарушит существующий код.
Предположим, у меня есть следующий класс и тесты:

Код: Выделить всё

public class TestSubject
{
public void EnsureNumberIsOdd(int inputValue)
{
if (inputValue % 2 != 1)
throw new ArgumentException("Must be an odd number", paramName: nameof(inputValue));
}
}

public class UnitTest2
{
private readonly TestSubject Subject;

public UnitTest2()
{
Subject = new TestSubject();
}

[Theory]
[InlineData(2)]
[InlineData(4)]
[InlineData(6)]
public void WhenValueIsEven_ThenThrowsException(int inputValue)
{
var exception = Assert.Throws(() => Subject.EnsureNumberIsOdd(inputValue));
Assert.Equal("inputValue", exception!.ParamName);
}

[Theory]
[InlineData(1)]
[InlineData(3)]
[InlineData(5)]
public void WhenValueIsOdd_ThenDoesNotThrowException(int inputValue)
{
Subject.EnsureNumberIsOdd(inputValue);
}
}
Теперь кто-то решает, что существует новое требование, согласно которому входное значение должно быть меньше 11, но они также хотят, чтобы это было скрыто за переключателем функции.

Код: Выделить всё

using Moq;
public interface IFeatureFlags
{
bool IsFlagEnabled(string flagName);
}

public class TestSubject(IFeatureFlags FeatureFlags)
{
public void EnsureNumberIsOdd(int inputValue)
{
if (inputValue % 2 != 1)
throw new ArgumentException("Must be an odd number", paramName: nameof(inputValue));

if (FeatureFlags.IsFlagEnabled("ValueMustBeLessThan11"))
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(inputValue, 11);
}
}

public class UnitTest2
{
private readonly Mock MockFeatureFlags;
private readonly TestSubject Subject;
private bool FeatureFlagIsEnabled;

public UnitTest2()
{
MockFeatureFlags = new Mock();
MockFeatureFlags
.Setup(x => x.IsFlagEnabled("ValueMustBeLessThan11"))
.Returns(() => FeatureFlagIsEnabled);

Subject = new TestSubject(MockFeatureFlags.Object);
}

[Theory]
[InlineData(2)]
[InlineData(4)]
[InlineData(6)]
public void WhenValueIsEven_ThenThrowsException(int inputValue)
{
// Same as before
}

[Theory]
[InlineData(1)]
[InlineData(3)]
[InlineData(5)]
public void WhenValueIsOdd_ThenDoesNotThrowException(int inputValue)
{
// Same as before
}

[Fact]
public void WhenFeatureFlagIsOn_AndValueIsNotLessThan10_ThenThrowsException()
{
FeatureFlagIsEnabled = true;
foreach(int i in new[] { 11, 13, 15, 17, 19 })
{
var exception = Assert.Throws(() => Subject.EnsureNumberIsOdd(i));
Assert.Equal("inputValue", exception!.ParamName);
}
}
}

  • Я добавил интерфейс IFeatureFlags и внедрил его в TestSubject.
  • Я добавил новый тест, чтобы убедиться, что исключение генерируется, если значение не меньше 11.
Что мне действительно нужно сделать, так это убедиться, что оба исходных теста проходят успешно, если флаг функции имеет значение true или false. Мои варианты:
  • Прокручивать значения [true, false].
  • Проблема: две проверки не выполняются изолированно. Для субъектов с состоянием это может привести к сбоям.
  • Дублируйте атрибуты [InlineData]. и иметь true для первой половины и false для второй половины.
  • Проблема: Кто-то может не добавить одновременно true и false [InlineData] при добавлении нового сценария.
  • Проблема: добавление новых флагов функций в один и тот же код вызывает экспоненциальный рост комбинаций, что слишком сложно контролировать и, скорее всего, это неправильно.
  • Дублируйте тесты.
  • Проблема: Как и выше, но дублирование методов тестирования гораздо сложнее, чем дублирование [InlineData] атрибуты.
Я рассматривал возможность использования атрибута [ClassData] для всех вариантов всех флагов, но не могу объединить их входные данные с существующие атрибуты [InlineData], поэтому мне пришлось отказаться от этой идеи.
В настоящее время я просматриваю все варианты в каждом тесте и гарантирую, что повторно инициализирую все состояние каждую петлю, но каждый раз, когда я смотрю на нее, меня немного тошнит во рту.
Есть ли элегантное решение этой проблемы?

Подробнее здесь: https://stackoverflow.com/questions/783 ... test-class
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»