1

我在单元测试中遇到了一个我无法解决的问题。我认为最简洁的说法是:

我希望能够使用 Theory InlineAutoMoqData 参数中提供的 Type 作为 Shouldly 的 Should.Throw 方法中的 T。这将允许我创建不同的行测试(我猜这是这个框架中的内联理论)期望不同的异常类型,如果有多个与方法相关联。

我不确定这是否可能,但这是单元测试本身的一个示例。

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

在被难住并发布此问题之前,我查看的问题是:为模板动态创建泛型类型使用包含类型的变量创建 Generic<T> 类型实例

这样的事情可能吗?

编辑:

我看到在 xUnit 中我可以通过 Assert.Throws(Type, Delegate) 方法实现这一点。

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

我仍然想知道是否有办法在我希望类型位于通用方法中时实现它。

4

1 回答 1

1

你不能,除了使用反射,类似于你提到的两个链接。

但是,您可以做一些小技巧来实现您想要的。这是丑陋和不切实际的,我不建议使用它,但只是为了它的乐趣......

创建一个包含参数化测试的泛型类:

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);
}

Assert.Throws正如您自己发现的那样,xUnit.net 有一个需要 a的非泛型,Type您应该使用它而不是这个 hack。

于 2016-04-13T20:30:35.087 回答