Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对在try主体中具有系统调用的异常处理程序进行单元测试?_C#_Unit Testing - Fatal编程技术网

C# 如何对在try主体中具有系统调用的异常处理程序进行单元测试?

C# 如何对在try主体中具有系统调用的异常处理程序进行单元测试?,c#,unit-testing,C#,Unit Testing,我面临着对上述代码的单元测试。强制系统抛出环境调用中的异常是否有魔力?我可以对方法进行更改,以便获得我想要的覆盖范围,但我也不太确定。。。有什么想法吗?回答这个问题有几个方面: 白盒测试 如果您真的想确保控制流按预期工作,那么必须将环境包装在一个单独的类中,并带有一个接口。。如果这样做,您可以模拟掉“MachineName”调用并模拟正常和错误行为。这种形式的测试非常接近于代码,如果实现中发生了一些小的变化,则需要花费大量的精力来维护 单元测试 在这里,您希望从外部测试方法的行为(无需逐行测试)

我面临着对上述代码的单元测试。强制系统抛出
环境
调用中的异常是否有魔力?我可以对方法进行更改,以便获得我想要的覆盖范围,但我也不太确定。。。有什么想法吗?

回答这个问题有几个方面:

  • 白盒测试
  • 如果您真的想确保控制流按预期工作,那么必须将环境包装在一个单独的类中,并带有一个接口。。如果这样做,您可以模拟掉“MachineName”调用并模拟正常和错误行为。这种形式的测试非常接近于代码,如果实现中发生了一些小的变化,则需要花费大量的精力来维护

  • 单元测试
  • 在这里,您希望从外部测试方法的行为(无需逐行测试),如果这样做,您将发现很难测试错误情况,因为静态调用是不可模拟的。。。您可能需要测试正常情况,在其他情况下。。。那么(你的决定)

  • 集成测试
  • 在这里,只有当一般的东西按预期工作时,您才真正不必关心实现细节(“使用此函数的函数中返回了某种名称”)

    第一部分需要做很多工作,因为您需要包装所有内容,在本例中,对于这个简单的代码,似乎需要做一些到很多的工作。。但是,您需要决定要为哪个粒度级别编写测试

    这将是包装器:

     public static string GetComputername() {
            try {
                return Environment.MachineName;
            } catch {
                return string.Empty; // make sure this never ever fails
            }
        }
    
    您可以这样修改该类:

    public interface ISystemWrapper
    {
        string MachineName();
    }
    
    public class SystemWrapper : ISystemWrapper
    {
        public string MachineName()
        {
            return Environment.MachineName;
        }
    }
    

    然后在测试中模拟SysWrapper

    如果可以模拟
    环境
    ,则可以创建一个抛出没有问题的属性

    public class ToTest
    {
        public static ISystemWrapper SysWrapper = new SystemWrapper();
    
        public static string GetComputername()
        {
            try
            {
                return SysWrapper.MachineName();
            }
            catch
            {
                return string.Empty; // make sure this never ever fails
            }
        }
    }
    

    static
    s在大多数情况下是一个糟糕的设计原则。其中一个原因是缺乏测试…是我还是这个静态没有改变什么?您可以使用类似于赝品和垫片的东西来拦截对
    环境.MachineName
    ()的调用,或者您可以沿着
    Func
    的线路注入一些东西作为解析器,而不是直接包装对
    Environment.MachineName
    的调用。一般来说,您应该只捕获您期望的异常,并且您知道正确的处理方法。您不需要通过单元测试就知道您的
    GetComputername()
    方法有缺陷;它在设计上是有缺陷的,因为你有一个笼统的
    catch
    子句,而不是捕获一些你准备处理的特定异常。如果你知道会发生什么异常,这会使测试更容易:你要么知道如何从实际的API调用中引发异常,要么可以对其进行模拟。我的观点:1)静态测试很糟糕,但在这里你无能为力;2)属性不应该抛出,但你也无能为力;3)你永远不应该抓住所有问题。在这里,您知道它可能(远程)无效。抓住这个。4) 不要对代码覆盖率上瘾,你真的不需要为每件事都写一个测试…非常好的答案。静态类在代码库中波动的方式是有害的。防止它的唯一方法就是像你在这里做的那样,在它爬进来之前把它掐掉。
    using System;
    
    namespace TestThrowExceptionInProperty
    {
        class Thrower {
            public int CheckMe {get{ throw new NotImplementedException (); }}
        }
    
        class MainClass
        {
    
            public static void Main (string[] args)
            {
                var thrower = new Thrower ();
                int bye = thrower.CheckMe;
                Console.WriteLine(bye);
            }
        }
    }