C# 如果构造函数抛出异常,是否有更合适的测试方法?

C# 如果构造函数抛出异常,是否有更合适的测试方法?,c#,.net,unit-testing,xunit.net,fluent-assertions,C#,.net,Unit Testing,Xunit.net,Fluent Assertions,通常,如果在某个方法中抛出异常,您将进行测试,如下所示。 我使用FluentAssertions: [Fact] public void Exception_gets_thrown() { // Arrange var foo = new Foo("validArgument"); // Act/Assert foo.Invoking(f => f.Bar(null)) // null is an invalid argument

通常,如果在某个方法中抛出异常,您将进行测试,如下所示。 我使用FluentAssertions

[Fact]
public void Exception_gets_thrown()
{
    // Arrange
    var foo = new Foo("validArgument");

    // Act/Assert
    foo.Invoking(f => f.Bar(null))            // null is an invalid argument
       .ShouldThrow<ArgumentNullException>();
}
[事实]
public void异常\u获取\u抛出()
{
//安排
var foo=新foo(“有效期”);
//行动/主张
调用(f=>f.Bar(null))//null是无效参数
.shouldtown();
}
但是,如果构造函数中抛出异常,如何进行测试? 我就是这样做的,但有没有更合适的方法 通过FluentAssertions

[Fact]
public void Constructor_throws_Exception()
{
    // Arrange
    Action a = () => new Foo(null);         // null is an invalid argument

    // Act/Assert
    a.ShouldThrow<ArgumentNullException>();
}
[事实]
public void构造函数\u抛出\u异常()
{
//安排
操作a=()=>new Foo(null);//null是无效参数
//行动/主张
a、 shouldtown();
}

这正是测试异常的方法,这也是
ShouldThrow()
ShouldNotThrow()
最初设计的目的。事实上,在下一个大版本(2.0.0)中,
Invoking()
方法可能会被标记为过时

我添加了一个助手方法,如下所示,用于测试构造函数:

static Action Constructor<T>(Func<T> func)
{
    return () => func();
}
静态动作构造函数(Func Func)
{
return()=>func();
}
然后我用这个:

Constructor(() => new Foo("bar", null))
.ShouldThrow<ArgumentNullException>()
.And
.ParamName
.Should()
.Be("baz");
[Fact]
public void Constructor_throws_Exception()
{    
    // Act/Assert
    Constructor(() => new Foo(null)).ShouldThrow<ArgumentNullException>();
}
Constructor(()=>newfoo(“bar”,null))
.ShouldThrow()
.及
.ParamName
.Should()
.Be(“baz”);
我知道这是个人喜好的问题,但我发现这比需要先声明和分配一个代理要干净一些

这将使原始问题中的代码如下所示:

Constructor(() => new Foo("bar", null))
.ShouldThrow<ArgumentNullException>()
.And
.ParamName
.Should()
.Be("baz");
[Fact]
public void Constructor_throws_Exception()
{    
    // Act/Assert
    Constructor(() => new Foo(null)).ShouldThrow<ArgumentNullException>();
}
[事实]
public void构造函数\u抛出\u异常()
{    
//行动/主张
构造函数(()=>newfoo(null)).ShouldThrow();
}
有一个内置的

FluentActions.Invoking(() => new Foo(null)).ShouldThrow<ArgumentNullException>();
FluentActions.Invoking(()=>newfoo(null)).ShouldThrow();

Invoking()方法过时了,真丢脸。我发现它比上面第二个测试中显示的动作机制更容易阅读。调用使一切都很好地结合在一起,因此目的很明显。@JackHughes我们引入Invoking()和ShouldThrow()变体的原因是为了去掉那些[ExpectedException]属性。Metro应用程序的单元测试项目甚至不再支持该属性。调用构造是一个很好的API IMHO BTW:)@DennisDoomen-这就是客户服务!!:)我们即将发布2.1,但它仍然处于;-)