Предположим, у меня есть следующий класс и тесты:
Код: Выделить всё
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);
}
}
Код: Выделить всё
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].
- Проблема: две проверки не выполняются изолированно. Для субъектов с состоянием это может привести к сбоям.
- Дублируйте атрибуты [InlineData]. и иметь true для первой половины и false для второй половины.
- Проблема: Кто-то может не добавить одновременно true и false [InlineData] при добавлении нового сценария.
- Проблема: добавление новых флагов функций в один и тот же код вызывает экспоненциальный рост комбинаций, что слишком сложно контролировать и, скорее всего, это неправильно.
- Дублируйте тесты.
- Проблема: Как и выше, но дублирование методов тестирования гораздо сложнее, чем дублирование [InlineData] атрибуты.
В настоящее время я просматриваю все варианты в каждом тесте и гарантирую, что повторно инициализирую все состояние каждую петлю, но каждый раз, когда я смотрю на нее, меня немного тошнит во рту.
Есть ли элегантное решение этой проблемы?
Подробнее здесь: https://stackoverflow.com/questions/783 ... test-class
Мобильная версия