期待异常时应用Arrange-Act-Assert模式的最佳方法

时间:2014-06-05 20:55:55

标签: c# unit-testing xunit.net arrange-act-assert

我正在尝试在编写单元测试时遵循Arrange-Act-Assert模式,我到了一个地方,我很困惑哪种方法会更好。我正在使用xUnit,我的第一个问题是:

//Arrange
int key = 1;
string value = "X";

//Act
board.Add(key, value);
var result = Assert.Throws<ArgumentException>(() => board.Add(key, value));

//Assert
Assert.IsType<ArgumentException>(result);

我的第二种方法是:

int key = 1;
string value = "X";

board.Add(key, value);

Assert.Throws<ArgumentException>(() => board.Add(key, value));

这是一种更好的方法吗?

编辑: 在wp.me/p4f69l-3z上发表了关于此的博客

5 个答案:

答案 0 :(得分:5)

您的第一次.Add电话应该是安排的一部分。将其视为行为的前提条件/设置。除此之外,您可以在Action中包含 act 以使其更好地阅读:

//Arrange
int key = 1;
string value = "X";
board.Add(key, value);

//Act
Action addingSameKeySecondTime = () => board.Add(key, value);

//Assert
Assert.Throws<ArgumentException>(addingSameKeySecondTime)
评论中提到的

FluentAssertions库使得这样的断言更加类似于句子

int key = 1;
string value = "X";
board.Add(key, value);

Action addingSameKeySecondTime = () => board.Add(key, value);

addingSameKeySecondTime.ShouldThrow<ArgumentException>();

答案 1 :(得分:1)

对我来说,源代码应该是自描述的,因此AAA注释更像是解决方法,可能无法提供足够的灵活性。 检查此库:Heleonix.Testing 您可以在Given / When / Then和AAA表单中编写JavaScript Jasmine / Jest样式中的测试。

答案 2 :(得分:0)

我会说你的第二个例子更好。 Assert.Throws将通过/未通过测试,因此没有理由得到它的结果并断言。当我写'将抛出'测试时,我将它保持在一两行:

[Test]
public void SomeMethod_NullSomething_ShouldThrow() {
    var something = MakeTarget();

    Assert.Throws<ArgumentNullException>(() => something.SomeMethod(null));
}

答案 3 :(得分:0)

实际上断言异常没有好的答案......就像测试事件一样,除了它们会中断代码流。假设你要测试add事件(我正在使用NUnit):

// Arrange
int key = 1;
var eventFired = false;
board.Added += (boardItem) => {
    eventFired = boardItem.key == key;
};

// Act
board.Add(key, "X");

// Assert
Assert.That(eventFired, Is.True);

测试异常时也是如此:

// Arrange
int key = 1;    
var exceptionRaised = false;
board.Add(key, "X");

// Act
try {
    board.Add(key, "X");
}
catch(InvalidOperationException ex) {
    exceptionRaised = true;
}

// Assert
Assert.That(exceptionRaised, Is.True);

所以Assert.Throws可以用来方便,但它不适合AAA风格。但是请记住,AAA并不是强制要求编写好的测试,最重要的是让测试易于理解。

答案 4 :(得分:0)

我通常采用以下方法

// Arrange
int key = 1;
string value = "X";
board.Add(key, value);

// Act & Assert
Assert.Throws<ArgumentException>(() => board.Add(key, value));

这是ASP.NET MVC中采用的方法(例如https://aspnetwebstack.codeplex.com/SourceControl/latest#test/Common/PrefixContainerTest.cs