2016-04-13 10 views
1

У меня проблема в модульном тестировании, которую я не смог решить. Я думаю, что самый краткий способ сказать это:В xUnit/Shouldly/AutoMoq/Autofixture, можем ли мы передать тип с использованием InlineAutoMoqData, который может использоваться как <T> в самом тесте?

Я хочу иметь возможность использовать тип, указанный в параметрах теории InlineAutoMoqData, как метод T Should Should's Should.Throw. Это позволило бы мне создать различные тесты Row (я полагаю, что это Inline Theories в этой структуре), ожидающих переменные типы исключений, если их несколько, связанных с методом.

Я не уверен, что это возможно, но вот пример самотестирования.

[Theory] 
[InlineAutoMoqData("bork", typeof(FileTypeNotRecognizedException))] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, Type expected, ProcessFactory sut) 
{ 
    Should.Throw<expected>(() => sut.Build(fileName)); 
} 

Вопросы, которые я смотрел, перед тем, как озадачен и размещение этого, были: Dynamically Create a generic type for template и Creating a Generic<T> type instance with a variable containing the Type

ли что-то подобное возможно?

Edit:

Я вижу, что в XUnit я могу добиться этого с помощью Assert.Throws (Тип, делегат) метод.

[Theory] 
[InlineAutoMoqData("bork", typeof(FileTypeNotRecognizedException))] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, Type expected, ProcessFactory sut) 
{ 
    Assert.Throws(expected,() => sut.Build(fileName)); 
} 

я все же хотел бы знать, если есть способ, чтобы достичь его, когда я хочу Тип быть в методе Generic.

ответ

1

Вы не можете, за исключением использования Reflection, аналогично двум указанным вами ссылкам.

Однако вы можете сделать небольшой трюк, чтобы достичь того, чего хотите. Это некрасиво и непрактично, и я не рекомендую использовать его, но только для удовольствия ...

Создать общий класс, содержащий ваш параметризированный тест:

public class Test<T> where T : Exception 
{ 
    public virtual void Build_ReturnsSpecificException_FileNamePassedIn(
     string fileName, 
     ProcessFactory sut) 
    { 
     Assert.Throws<T>(() => sut.Build(fileName)); 
    } 
} 

Для каждого параметра (Тип исключения) вы создаете класс, унаследованный от родового один, переопределить метод тестирования и использовать InlineAutoMoqData:

public class TestFileNotFound : Test<FileTypeNotRecognizedException> 
{ 
    [Theory] 
    [InlineAutoMoqData("bork")] 
    public override void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
     ProcessFactory sut) 
    { 
     base.Build_ReturnsSpecificException_FileNamePassedIn(fileName, sut); 
    } 
} 
public class TestAnotherException : Test<Exception> 
{ 
    [Theory] 
    [InlineAutoMoqData("borg")] 
    public override void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
     ProcessFactory sut) 
    { 
     base.Build_ReturnsSpecificException_FileNamePassedIn(fileName, sut); 
    } 
} 

конечно, вы могли бы сделать то же самое, используя общий метод вместо родового класса, но это кажется глупым, хорошо:

public void Build_ReturnsSpecificException_FileNamePassedIn<TException>(string fileName, 
    ProcessFactory sut) 
    where TException : Exception 
{ 
    Assert.Throws<TException>(() => sut.Build(fileName)); 
} 

[Theory] 
[InlineAutoMoqData("bork")] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
    ProcessFactory sut) 
{ 
    Build_ReturnsSpecificException_FileNamePassedIn<FileTypeNotRecognizedException>(fileName, sut); 
} 

[Theory] 
[InlineAutoMoqData("borg")] 
public void Build_ReturnsAnotherException_FileNamePassedIn(string fileName, 
    ProcessFactory sut) 
{ 
    Build_ReturnsSpecificException_FileNamePassedIn<Exception>(fileName, sut); 
} 

Как вы узнали себя, xUnit.net имеет не родовое Assert.Throws, который принимает Type и вы должны использовать что вместо этого хака.

+0

Почему бы не поместить атрибуты '[Теория] и' [InlineAutoMoqData] 'в тест базового класса? http://blog.ploeh.dk/2011/05/09/GenericunittestingwithxUnit.net. Тогда вам не понадобятся все эти переопределения. –

+0

Вы правы, если встроенные данные (имя_файла) не зависят от исключения. Кажется, это не так. Похоже, что исключение изменится с изменением имени файла, в противном случае, в чем смысл встроить исключение вообще? –