C# 如何对作为tracesource对象包装器的自定义记录器进行单元测试

C# 如何对作为tracesource对象包装器的自定义记录器进行单元测试,c#,unit-testing,logging,trace,C#,Unit Testing,Logging,Trace,我有一个关于TraceSource类的包装器。我想知道如何进行单元测试。由于我需要配置app.config文件,以便将跟踪侦听器添加到TraceSource对象,添加SwtichSource等。因此,在单元测试dll中手动添加app.config文件并将其配置为执行单元测试是否有效?我知道我们可以逐步做到这一切,但我在TraceSource周围创建一个包装的方式看起来很棘手,或者可能是不可能的。欢迎提出任何建议 public class Logger : ILogger { priva

我有一个关于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);
    }
  }

与其让此类为自己创建
TraceSource
,不如通过构造函数注入将
TraceSource
注入其中。这样,在单元测试中,可以使用侦听器初始化TraceSource,让您记录对它所做的操作


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

因为您说的是单元测试,所以单元测试(相对于验收或集成测试)不应该到达外部组件,包括操作系统,我假设您想测试这个类的逻辑,但对测试日志消息是否真正到达目的地(文件、数据库、云或其他)不感兴趣

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

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

    ...

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

    ...
}

我个人会制作一个更通用的界面(比如
ILogTarget
),如果您改变主意并确保没有与此紧密耦合,那么它可以由其他日志框架实现,但要继续,这会起作用。

这有意义吗?@StriplingWarrior将tracesource实例注入记录器构造函数时,我是否应该进行依赖注入?依赖注入是否适用于多线程场景?重要的是,访问记录器类的每个类都要进行跟踪/记录。我需要这个类的名称,如果我通过依赖项注入将tracesource注入Logger类的构造函数,我不确定是否能够这样做?因为TraceSource构造函数将具有类的名称,如TraceSource source=new TraceSource(“正在进行跟踪/日志记录的类的名称”)。@user2913184:您可以有两个构造函数:一个像我描述的,另一个说:
public Logger(string nameOfComponent):这(new-TraceSource(nameOfComponent))
。这样,您可以在需要时注入TraceSource(例如,用于单元测试),但仍然有一个用于初始化静态实例的易于使用的构造函数。不,实际上我正在尝试测试类逻辑/功能以及oracle数据库的日志记录。@user2913184那么这不是单元测试,这是一个集成或验收测试。“在内存中运行(例如,没有数据库或文件访问)”同意。这将是一个集成测试。