c# - 如何检查是否已抛出任何异常?

标签 c# exception dispose

我正在为一项服务进行一些测试自动化,并想出了一种巧妙的方法来将一些常见的设置和验证汇总到“ session ”类中。

从概念上讲,测试用例可能如下所示:

using (var managerSession = new Session(managerRole))
{
    // A manager puts some items in warehouse
}

using (var employeeSession = new Session(employeeRole))
{
    // An employee moves items from warehouse to store
}

using (var customerSession = new Session(customerRole))
{
    // A customer can buy items from the store
}

在 Session 对象构造函数中,我建立了一个到我正在测试的服务的连接,每个角色都使用适当的身份验证等,并且在 session Dispose() 方法中,我有一个通用的验证 block ,例如,检查没有服务器- 在 session 生命周期内出现端错误或警告。

当然,这有点滥用 IDispose 模式,如果 using block 中的测试代码抛出异常并且验证 block 也抛出异常,则第二个异常将掩盖第一个异常。

从概念上讲,如果我们有这种情况:

using (var managerSession = new Session(managerRole))
{
    Assert.IsTrue(managerSession.DoJob(), "Manager did not do his job");
}

...并且断言失败或对 managerSession.DoJob() 的调用引发异常,那么我希望 Session Dispose() 方法跳过验证 block ,即

public void Dispose()
{
    if (NoExceptionThrown())
    {
         Assert.IsFalse(this.serviceConnection.HasErrors(), "Service connection has errors");
    }

    this.serviceConnection.Dispose();
}

...使得测试方法永远不会因“服务连接有错误”而失败,如果它实际上因“经理没有完成他的工作”而失败

我的问题是:是否可以在此处实现“NoExceptionThrown()”方法?是否有一些可以检查的全局属性,或者隐藏在 Thread.CurrentThread 中可以利用的东西?

更新:

我的问题是不是如何重构它:-)

我当然可以改用这个模式:

Session.ForRole(managerRole, (session) => { /* Test code here */ });

使用静态方法 ForRole() 定义如下

public static void ForRole(Role r, Action<Session> code)
{
    var session = new Session(r);
    try 
    {
        code(session);
        Assert.IsFalse(session.serviceConnection.HasErrors());
    }
    finally 
    {
        session.Dispose();
    }
}

但我很好奇是否有某种方法可以像上面描述的那样获取异常状态。

最佳答案

如果有 IDisposable.Dispose 的重载会很有用,它采用 Exception 类型的参数来指示什么异常(如果有的话)正在挂起finally 与其清理关联的上下文。虽然 Dispose 方法通常不应该关心异常的细节,但在 Dispose 方法期间可能会出现情况,应该将其报告给调用者。从 Dispose 抛出的任何异常都将替换在调用者的 finally 上下文中挂起的任何异常,因此如果 Dispose 方法可以在替换它之前封装一个挂起的异常。不幸的是,不存在这样的功能,我不希望添加任何功能。

虽然有一些 hack 可以用来实现类似预期的效果,但唯一语义正确的方法是将异常作为 Dispose 方法的参数。任何其他方法的问题是 Dispose 可能会在多个嵌套的 finally block 中运行,其中一些有未决的异常,而另一些则没有;检查执行上下文以确定嵌套最深的 finally block 的状态的代码可能会失败,如果该 block 不是保护被处置对象的生命周期的 block 。

关于c# - 如何检查是否已抛出任何异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17866511/

相关文章:

c# - 使用前生成并处理?

c# - 在 EventHandler 中尝试 Set() 时,如何检查 ManualResetEvent 是否已被处置?

c# - try catch FormatException 错误失败。只有 Exception 才能捕获它?

c# - 应用发布时的异常控制?

c# - 编辑列表包含本身包含对象的对象,等等

javascript - 异常 : "The remote host closed the connection. The error code is 0x80070057"

c++ - 编译器为类生成 noexcept ctor,其成员在没有此类保证的情况下构造

java - 处理后重新启动 JFrame

c# - 如何使用 Type.InvokeMember 调用显式实现的接口(interface)方法?

c# - 从 SQL(C# 和 Entity Framework )到 mongodb(Go 和 mgo)