使用 NSubstitute 模拟出现问题时抛出异常的方法

Posted

技术标签:

【中文标题】使用 NSubstitute 模拟出现问题时抛出异常的方法【英文标题】:Mocking a method that throws exception if something went wrong using NSubstitute 【发布时间】:2018-08-13 10:11:37 【问题描述】:

我在我的 .NET Core 应用程序中实现了一项服务,我调用它来验证我的模型。不幸的是,如果服务(不是我的)无效,服务(不是我的)会抛出异常,如果它是有效的(因为它是一个 void 方法),它只会以 200 OK 响应。

所以基本上我会这样做:

try 
    await _service.ValidateAsync(model);
    return true;
 catch(Exception e) 
    return false;

我试图模拟ValidateAsync 内部的方法,它将请求发送到我实现的服务。 ValidateAsync 仅将我的控制器的输入从我前端的某些东西转换为 Validate 方法可以理解的东西。

但是,我无法真正了解我应该如何测试它。这是我尝试过的方法,但对我来说没有任何意义。

[TestMethod]
public void InvalidTest() 
    var model = new Model(); // obviously filled out with what my method accepts

    _theService.Validate(model)
        .When(x =>  ) //when anything
        .Do(throw new Exception("didn't work")); //throw an exception

    //Assert should go here.. but what should it validate?

所以基本上:When this is called -> throw an exception

我应该如何使用 NSubstitute 来模拟它?

【问题讨论】:

@mjwills 这只是为了展示我如何处理我找到的服务的响应。由于如果模型无效,服务会抛出异常,因此我必须像这样处理“响应”/验证。 @mjwills 没有必要,因为不可能实现这个服务作为示例。我的帖子完美地解释了我的问题。 【参考方案1】:

根据目前的解释,假设类似于

public class mySubjectClass 

    private ISomeService service;

    public mySubjectClass(ISomeService service) 
        this.service = service;
    

    public async Task<bool> SomeMethod(Model model) 
        try 
            await service.ValidateAsync(model);
            return true;
         catch(Exception e) 
            return false;
        
    


为了覆盖SomeMethod 的错误路径,依赖项需要在调用时抛出异常,以便可以按预期执行测试。

[TestMethod]
public async Task SomeMethod_Should_Return_False_For_Invalid_Model() 
    //Arrange
    var model = new Model()  
        // obviously filled out with what my method accepts
    ;

    var theService = Substitute.For<ISomeService>();
    theService
        .When(_ => _.ValidateAsync(Arg.Any<Model>()))
        .Throw(new Exception("didn't work"));

    var subject = new mySubjectClass(theService);

    var expected = false;

    //Act
    var actual = await subject.SomeMethod(model);

    //Assert
    Assert.AreEqual(expected, actual);

【讨论】:

太棒了。效果很好,很有意义。非常感谢! 好的,我收回这句话。它确实有效,因为我没有意识到 ValidateAsync 方法中的方法实际上会抛出异常,因为 AutoRest 出现错误。我正在尝试模拟 AutoRest 生成方法(我实现的服务)的响应,该方法在最低级别返回 HtttpOperationStatus 或引发异常。似乎不可能模拟这些扩展方法,而不会造成巨大的混乱。

以上是关于使用 NSubstitute 模拟出现问题时抛出异常的方法的主要内容,如果未能解决你的问题,请参考以下文章

NSubstitute ForPartsOf模拟除一个以外的所有方法?

加载本机 dll 时抛出 ExecutionEngineException

单元测试-隔离框架NSubstitute

removeItem(at: ) 成功删除目标文件时抛出异常

为啥mysql PDO不会在失败时抛出错误[重复]

Wordpress 在加载 http_headers_1.js 时抛出错误