Я почти уверен, что вы ищете Поведения (см. Также этот тест строки со статьями поведения ). Вы определите поведение, которому должна удовлетворять каждая реализация (поля It
) в специальном классе, который разделяет SUT и вспомогательные поля (при необходимости).
[Behaviors]
public class DeferredExecutionProcessor
{
It should_not_have_enumerated_the_original_samples = () =>
{
_.Original.DidNotReceive().GetEnumerator();
((IEnumerable)_.Original).DidNotReceive().GetEnumerator();
};
protected static Context _;
}
Каждая из ваших реализаций должна объявить, что они ведут себя как этот специальный класс. У вас уже был довольно сложный базовый класс с общей настройкой и поведением, поэтому я буду его использовать (я предпочитаю более простую, более явную настройку).
public abstract class AudioProcessorContext<TSutFactory>
where TSutFactory : ISutFactory<IAudioProcessor>, new()
{
// I don't know Behaves_like works with field initializers
Establish context = () =>
{
Sut = new TSutFactory().CreateSut();
_ = new Context();
_.Original = Substitute.For<IEnumerable<ISample>>();
}
protected static IAudioProcessor Sut;
protected static Context _;
}
Ваш базовый класс определяет общую настройку (захват перечисления контекста), поведение (обработка с определенным значением через параметр типа) и даже объявление поля поведений (опять же, благодаря параметру универсального типа, это будет выполнено за каждый конкретный).
[Subject("Audio Processor Impl 1")]
public class when_impl1_processes_audio : AudioProcessorContext<AudioProcessorImpl1Factory>
{
Because of = () => Sut.Process(_.Original);
Behaves_like<DeferredExecutionProcessor> specs;
}
[Subject("Audio Processor Impl 2")]
public class when_impl2_processes_audio : AudioProcessorContext<AudioProcessorImpl2Factory>
{
Because of = () => Sut.Process(_.Original);
Behaves_like<DeferredExecutionProcessor> specs;
}
[Subject("Audio Processor Impl 3")]
public class when_impl3_processes_audio : AudioProcessorContext<AudioProcessorImpl3Factory>
{
Because of = () => Sut.Process(_.Original);
Behaves_like<DeferredExecutionProcessor> specs;
}
Кроме того, вы получите вывод для каждого из полей It
для каждого из реализующих классов. Таким образом, ваши отчеты по контексту / спецификации будут полными.