单元测试静态构造函数与/不同的配置值

时间:2012-07-01 04:27:37

标签: c# unit-testing static-constructor

我有一个带有静态构造函数的类,我用它来读取app.config值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,因此我可以为每个测试执行静态构造函数 - 但我在这里有两个问题:
1.我不知道如何在单独的应用程序域中运行每个测试运行 2.如何在运行时更改配置设置?

有人可以帮我这个吗?或者任何人有更好的解决方案?感谢。

4 个答案:

答案 0 :(得分:0)

您无需测试.Net是否能够从配置文件加载数据 相反,尝试专注于测试自己的逻辑。

更改您的类,使其从构造函数(或通过属性)获取配置值,然后像对待任何其他依赖项一样对其进行测试。

在此过程中,您还将课程移至SRP

根据配置加载 - 将此逻辑集中在一个单独的非静态类中。


编辑:
将配置逻辑分成另一个类。像这样的东西:

public static class ConfigurationLoader
{
    static ConfigurationLoader()
    {
        // Dependency1 = LoadFromConfiguration();
        // Dependency2 = LoadFromConfiguration();
    }

    public static int Dependency1 { get; private set; }
    public static string Dependency2 { get; private set; }
}

然后,当您实例化类时,请使用依赖项注入它:

public class MyClass
{
    private readonly int m_Dependency1;
    private readonly string m_Dependency2;

    public MyClass(int dependency1, string dependency2)
    {
        m_Dependency1 = dependency1;
        m_Dependency2 = dependency2;
    }

    public char MethodUnderTest()
    {
        if (m_Dependency1 > 42)
        {
            return m_Dependency2[0];
        }

        return ' ';
    }
}

public class MyClassTests
{
    [Fact]
    public void MethodUnderTest_dependency1is43AndDependency2isTest_ReturnsT()
    {
        var underTest = new MyClass(43, "Test");
        var result = underTest.MethodUnderTest();
        Assert.Equal('T', result);
    }
}

...

var myClass = new MyClass(ConfigurationLoader.Dependency1, ConfigurationLoader.Dependency2);

您可以继续使用IOC容器,但是通过这种简单的可测试设计解决了使用不同输入测试MyClass的问题。

答案 1 :(得分:0)

就个人而言,我只是将静态构造函数粘贴到静态方法中,然后在静态块中执行该方法。

答案 2 :(得分:0)

如果您从(Web)ConfigurationManager.AppSettings读取,那只是一个NameValueCollection,那么您可以直接使用从任何NameValueCollection读取的代码替换直接读取ConfigurationManager.AppSettings的代码。

将实际配置解析为静态ctor的静态方法。静态ctor调用静态方法并传递ConfigurationManager.AppSettings,但您可以从测试代码中调用该解析器方法,并验证配置解析而不实际触及文件,或者弄乱appdomains。

但从长远来看,确实按照建议的方式注入您的配置参数。创建配置类,在应用程序启动时读取实际值,并设置IoC容器以向所有请求者提供相同的配置实例。

这使得进一步的测试也变得更容易,因为您的类不会从全局静态配置实例中读取。您只需传入特定的配置实例即可进行差异测试。当然,为您的测试创建一个工厂方法,构建一个全局配置,这样您就不必一直手动执行...

答案 3 :(得分:0)

我最近也遇到了同样的问题。唯一的区别是配置值来自数据库而不是来自app.config。我可以使用TypeInitializer来解决它。

[Test]
public void TestConfigurationInStaticConstructor()
{
    // setup configuraton to test
    // ...

    // init static constructor
    ReaderTypeInit();

    // Assert configuration effect
    // ...

    // reset static ctor to prevent other existing tests (that may depend on original static ctor) fail
    ReaderTypeInit();
}

// helper method
private void ReaderTypeInit()
{
    typeof(< your class with static ctor>).TypeInitializer.Invoke(null, new object[0]);
}