代码之家  ›  专栏  ›  技术社区  ›  Martin

努尼特期待例外

  •  47
  • Martin  · 技术社区  · 14 年前

    我有一组测试用例,其中一些应该抛出异常。因此,我已经为这些测试设置了属性,以期望出现这样的异常:

    [ExpectedException("System.NullReferenceException")]
    

    当我在本地运行测试时,一切都很好。但是,当我将测试转移到运行TeamCity的CI服务器时,所有预期异常的测试都会失败。这是一个已知的错误。

    我知道还有 Assert.Throws<> Assert.Throws 努尼特提供的方法。

    我的问题是如何使用这些属性而不是当前使用的属性?

    我环顾了一下StackOverflow,尝试了一些似乎对我没用的方法。

    有没有一个简单的单线解决方案来使用这个?

    3 回复  |  直到 11 年前
        1
  •  84
  •   Mark Rushakoff    14 年前

    我不确定您尝试过的是什么给您带来了麻烦,但是您可以简单地将lambda作为第一个参数传入assert.throws。以下是我的一个测试中通过的一个:

    Assert.Throws<ArgumentException>(() => pointStore.Store(new[] { firstPoint }));
    

    好吧,这个例子可能有点冗长。假设我做了个测试

    [Test]
    [ExpectedException("System.NullReferenceException")]
    public void TestFoo()
    {
        MyObject o = null;
        o.Foo();
    }
    

    通常会通过,因为 o.Foo() 将引发空引用异常。

    然后你会放下 ExpectedException 属性并将调用包装到 O() 在一个 Assert.Throws .

    [Test]
    public void TestFoo()
    {
        MyObject o = null;
        Assert.Throws<NullReferenceException>(() => o.Foo());
    }
    

    Assert.Throws “试图调用代码段(表示为委托),以验证它是否引发了特定的异常。”。 () => DoSomething() 语法表示 兰姆达 ,本质上是一个匿名方法。所以在这种情况下,我们告诉你 断言投掷 执行代码段 O() .

    所以,不,您不只是像添加属性那样添加一行;您需要显式包装测试中将引发异常的部分,在调用 断言投掷 . 你不 必要地 必须使用lambda,但这通常是最方便的。

        2
  •  9
  •   Jerod Houghtelling    14 年前

    下面是一个使用两种方法的简单示例。

    string test = null;
    Assert.Throws( typeof( NullReferenceException ), () => test.Substring( 0, 4 ) );
    Assert.Throws<NullReferenceException>( () => test.Substring( 0, 4 ) );
    

    如果你不想用羊羔肉。

    [Test]
    public void Test()
    {
        Assert.Throws<NullReferenceException>( _TestBody );
    }
    
    private void _TestBody()
    {
        string test = null;
        test.Substring( 0, 4 );
    }
    
        3
  •  2
  •   Ross Patterson    13 年前

    默认情况下,TeamCity使用的是Nunit 2.2.10,它没有ExpectedException。查看TeamCity的“Nunit for Nant”文档,了解如何将其更改为更现代的版本,包括TeamCity提供的特定版本列表。