c# - 无法对调用静态方法的方法进行单元测试,我该如何重新设计这个程序?

标签 c# .net unit-testing oop static

我有一个类在整个程序中将日志写入文本文件。我认为将方法设置为 static 是个好主意,因为它只有几个方法,并且会在程序的许多不同部分调用。此方法在程序开始时调用一次以创建初始文件。

public static void CreateAuditLog()
{
    var fileName = Path.Combine(filePath, 
        $@"AuditFile{DateTime.Now:yyyy-MM-dd_hh-mm-ss-fff}.txt");

    writer = new StreamWriter(new FileStream(fileName,
        FileMode.CreateNew, FileAccess.Write));

    GetAuditLogFileSize();
}

但是在编写单元测试时,我不知道不能测试调用静态方法的方法。 (来自代码库的示例方法)

public Decimal CalculateCurrentBalance
{
    get
    {
        var balance = TotalAmountBilled - TotalAmountPaid;
        Audit.Message(2, $"Balance: {balance} for: {Name}");
        return TotalAmountBilled - TotalAmountPaid;
    }
}

消息方法有很多细节,所以我不会在这里全部发布,但基本上它接受一个数字和一条消息来记录到文本文件。流编写器在 CreateAuditLog() 中有意保持打开状态,以便可以在许多不同的地方调用 Message() 并将消息写入日志文件。

public static void Message(int auditLevel, string message)

我觉得我设计这个程序的方式很糟糕。有人对我如何重新设计它有什么建议吗?如果不在程序中的每个其他类上创建我的日志记录类的实例,我不确定如何才能做到这一点。

最佳答案

不要在所有其他类中创建实例; 注入(inject)一个。

这是单元测试的基础之一;依赖注入(inject)。类不创建或直接访问它们的依赖项,它们被传递给使用的依赖项。在这种情况下,如果您的 Log 类实现了 ILogger(您编写的接口(interface)),那么您的类将如下所示:

public class MyInjectedClass
{
     private readonly ILogger logger;
     public MyInjectedClass(ILogger logger)
     {
        this.logger = logger;
     }

     public void SomeMethod()
     {
        logger.Message();
     }
}

当然,现在您必须到处传递 ILogger 的实例,这是一个很大的麻烦。幸运的是,有很多库,例如 NInjectAutofac 可以为您连接所有依赖项。这将需要一些重构,但一旦完成,您只需将日志记录类注册为 ILogger 接口(interface)的单例,它将自动注入(inject)到每个将其作为依赖项的类中。

(MS 有一个 DI 库,如果您正在使用它,它也包含在 .NET Core 中)

界面看起来像这样:

public interface ILogger
{
     void Message(string msg);
}

关于c# - 无法对调用静态方法的方法进行单元测试,我该如何重新设计这个程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51049922/

相关文章:

c# - 如何在 Quartz 调度程序中每 3 分钟运行一次?

.net - C# 确保有效的枚举值 - 面向 future 的方法

php - 如何在 Yii2 中使用 Codeception 运行单元测试?

C# 对具有分隔符的文本文件从高到低进行排序

c# - 从 IronPython 调用 C# 函数

c# - 如何有效地丢弃数组并用新值填充它?

c# - 等待池线程完成

c# - 将多个 ObservableCollection 绑定(bind)到一个 ObservableCollection

java - App Engine Java JDO 中的单元测试 XG 跨组事务

c# - 为什么单元测试中未处理的异常不会导致使用 M​​STest 失败?