如何对自定义记录器进行单元测试,该记录器是traceource对象的包装器

时间:2016-03-14 02:46:28

标签: c# unit-testing logging tracing

我有一个TraceSource类的包装器。我想知道如何对它进行单元测试。由于我需要配置app.config文件以便向TraceSource对象添加跟踪侦听器,因此添加SwtichSource等。因此,在单元测试dll中手动添加app.config文件并将其配置为进行单元测试是否有效?我知道我们可以以原理方式完成所有这些,但是我在TraceSource周围创建了一个包装器的方式看起来非常痒或者可能是不可能的。任何建议都将受到欢迎。

public class Logger : ILogger
{

    private const int ERROR_EVENT_ID = 2;
    private const int DEBUG_EVENT_ID = 5;
    private  static TraceSource source;

    public Logger(string nameOfComponent)
    {
         source = new TraceSource(nameOfComponent);
    }

    public  void LogDebug(string message, string methodName)
    {
        if (string.IsNullOrEmpty(message) || string.IsNullOrEmpty(methodName))
            throw new ArgumentNullException("message, methodName can't be null or empty");

        source.TraceEvent(TraceEventType.Verbose, DEBUG_EVENT_ID);
    }

    public  void LogError(string methodName, Exception ex)
    {
        LogError(null, methodName, ex);
    }

    public  void LogError(string message, string methodName, Exception ex)           {
        if (String.IsNullOrEmpty(message) || String.IsNullOrEmpty(methodName) || ex == null)
            throw new ArgumentNullException("message, methodName and exception can't be null or empty");

        source.TraceData(TraceEventType.Error, ERROR_EVENT_ID, message, methodName, ex);
    }
  }

2 个答案:

答案 0 :(得分:1)

不是让这个类为自己创建TraceSource,而是通过构造函数注入将TraceSource注入其中。这样,在单元测试中,您可以使用侦听器初始化TraceSource,以便记录已对其执行的操作。

您还应该确保您的source字段不是静态的,因为它是由非静态构造函数初始化的,并且由非静态方法使用。

答案 1 :(得分:0)

既然你说单元测试,并且单元测试(而不是接受或集成测试)不应该到外部组件(包括操作系统),我假设你想要测试这个类的逻辑,但不是'有兴趣测试日志消息实际上是否到达目的地(文件或数据库或云或其他)。

如果是这样,那么解决方案是将TradeSource类包装在一个没有逻辑的非常薄的包装器中(因此不需要进行单元测试)。这将允许您轻松地注入它或使用工厂创建它,模拟它,因此单元测试Logger类中的逻辑。像这样:

public class TraceSourceLogTarget : ITraceSourceLogTarget
{
    private TraceSource _traceSource = new TraceSource();

    ...

    public void TraceEvent(TraceEventType eventType, int eventId)
    {
        _traceSource.TraceEvent(eventType, eventId);
    }

    ...
}

我个人会创建一个更通用的接口(比如ILogTarget)并让它可以被其他日志框架实现,如果你改变主意并确保你没有紧密耦合到这个,而是开始,这会奏效。