C# 如何对在try主体中具有系统调用的异常处理程序进行单元测试?
我面临着对上述代码的单元测试。强制系统抛出C# 如何对在try主体中具有系统调用的异常处理程序进行单元测试?,c#,unit-testing,C#,Unit Testing,我面临着对上述代码的单元测试。强制系统抛出环境调用中的异常是否有魔力?我可以对方法进行更改,以便获得我想要的覆盖范围,但我也不太确定。。。有什么想法吗?回答这个问题有几个方面: 白盒测试 如果您真的想确保控制流按预期工作,那么必须将环境包装在一个单独的类中,并带有一个接口。。如果这样做,您可以模拟掉“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);
}
}
}