其他分享
首页 > 其他分享> > CodeGo.net>如何测试方法抛出特定输入异常

CodeGo.net>如何测试方法抛出特定输入异常

作者:互联网

在下面的方法中,当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始终返回false.

我可以直接替代TestRepository,但是随后我会将项目插入数据库,这是我不想做的.如何在不将项目插入数据库的情况下使用NUnit和NSubstitute测试存储库异常?

解决方法:

您所做的事情有几个问题.正如评论中已经说过的那样,用模拟/替换您要测试的类通常是一个坏主意.模拟和替代用于允许您控制通过测试代码的逻辑流,而不是替换测试代码.

由于显示的代码除了模型类之外没有任何依赖关系,因此在这种情况下根本没有理由使用Substitute.如果您的代码看起来像这样(伪代码),则可以使用Substitute

if(model.Test == null) {
   throw someException
}
_someDependency->Create(model.Value1, model.Value2, model.Test)

在上面的代码中,_someDependency是一些基础数据库交互类,已通过其构造函数注入到存储库中.然后,您将可以为_someDependency创建一个Substitute,以影响Create方法的流程,或验证与该依赖项的交互.

就目前测试方法而言,没有理由不能只传递具有test == null的Model.方法中的逻辑流程是这样的:如果测试失败,则您不会期望将数据写入数据库,这就是检查的重点.因此,您的测试可能看起来像这样:

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

标签:nsubstitute,nunit,c,asp-net-mvc
来源: https://codeday.me/bug/20191028/1953210.html