如何测试方法是否在特定输入上抛出异常
How to test that a method throws an exception on specific input
在下面的方法中,当 model.test
为空时,我希望此方法抛出异常。
public bool Create(Test model)
{
if (model.test == null)
{
throw new InvalidOperationException("nanana.");
}
try
{
return true;
}
catch (InvalidOperationException ex) { throw; }
}
这是我当前的测试:
[Test]
public void Only_one_property_should_be_set()
{
var rep = Substitute.For<ITestRepository>();
var x = rep.Create(model.ToEntity());
Assert.Throws<InvalidOperationException>(() => rep.Create(model.ToEntity()));
}
它不起作用,因为 x returns 始终为 false。
我可以直接替换 TestRepository
,但随后我会将项目插入数据库,但我不想这样做。如何在不将项目插入数据库的情况下使用 NUnit 和 NSubstitute 测试存储库异常?
您的操作存在几个问题。正如评论中已经说过的那样,模拟/替换您要测试的 class 通常不是一个好主意。 Mocks 和 Substitutes 用于允许您通过被测代码控制逻辑流,而不是替换被测代码。
由于您显示的代码除了模型 class 之外没有任何依赖项,因此在这种情况下您根本没有理由使用替代品。如果您的代码看起来像这样(伪代码),您将使用 Substitute
if(model.Test == null) {
throw someException
}
_someDependency->Create(model.Value1, model.Value2, model.Test)
在上面的代码中,_someDependency
是一些基础数据库交互 class,已通过其构造函数注入到存储库中。然后,您可以为 _someDependency
创建一个替代品,以影响 Create
方法的流程,或验证与依赖项的交互。
就目前的方法测试而言,没有理由不能只传入具有 test==null
的模型。该方法中的逻辑流程是这样的,如果该测试失败,您不会期望将数据写入数据库,这就是检查的重点。所以,你的测试可以简单地看起来像这样:
[Test]
public void CreateShouldThrowIfModelTestIsNull()
{
var testModel = model.ToEntity();
var sut = new TestRepository();
testModel.test = null;
try {
sutCreate(testModel);
Assert.Fail("Expected Exception");
} catch(InvalidOperationException ex) {
Assert.AreEqual("nanana.", ex.Message);
}
}
在下面的方法中,当 model.test
为空时,我希望此方法抛出异常。
public bool Create(Test model)
{
if (model.test == null)
{
throw new InvalidOperationException("nanana.");
}
try
{
return true;
}
catch (InvalidOperationException ex) { throw; }
}
这是我当前的测试:
[Test]
public void Only_one_property_should_be_set()
{
var rep = Substitute.For<ITestRepository>();
var x = rep.Create(model.ToEntity());
Assert.Throws<InvalidOperationException>(() => rep.Create(model.ToEntity()));
}
它不起作用,因为 x returns 始终为 false。
我可以直接替换 TestRepository
,但随后我会将项目插入数据库,但我不想这样做。如何在不将项目插入数据库的情况下使用 NUnit 和 NSubstitute 测试存储库异常?
您的操作存在几个问题。正如评论中已经说过的那样,模拟/替换您要测试的 class 通常不是一个好主意。 Mocks 和 Substitutes 用于允许您通过被测代码控制逻辑流,而不是替换被测代码。
由于您显示的代码除了模型 class 之外没有任何依赖项,因此在这种情况下您根本没有理由使用替代品。如果您的代码看起来像这样(伪代码),您将使用 Substitute
if(model.Test == null) {
throw someException
}
_someDependency->Create(model.Value1, model.Value2, model.Test)
在上面的代码中,_someDependency
是一些基础数据库交互 class,已通过其构造函数注入到存储库中。然后,您可以为 _someDependency
创建一个替代品,以影响 Create
方法的流程,或验证与依赖项的交互。
就目前的方法测试而言,没有理由不能只传入具有 test==null
的模型。该方法中的逻辑流程是这样的,如果该测试失败,您不会期望将数据写入数据库,这就是检查的重点。所以,你的测试可以简单地看起来像这样:
[Test]
public void CreateShouldThrowIfModelTestIsNull()
{
var testModel = model.ToEntity();
var sut = new TestRepository();
testModel.test = null;
try {
sutCreate(testModel);
Assert.Fail("Expected Exception");
} catch(InvalidOperationException ex) {
Assert.AreEqual("nanana.", ex.Message);
}
}