Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有不同配置值的单元测试静态构造函数_C#_Unit Testing_Static Constructor - Fatal编程技术网

C# 具有不同配置值的单元测试静态构造函数

C# 具有不同配置值的单元测试静态构造函数,c#,unit-testing,static-constructor,C#,Unit Testing,Static Constructor,我有一个带有静态构造函数的类,用于读取app.config值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,这样我就可以为每个测试执行静态构造函数——但我这里有两个问题: 1.我不知道如何在单独的应用程序域和中运行每个测试运行 2.如何在运行时更改配置设置 有人能帮我吗?或者谁有更好的解决方案?谢谢。您不需要测试.Net是否能够从配置文件加载数据。 相反,试着集中精力测试你自己的逻辑 更改类,使其从构造函数(或通过属性)获取配置值,然后像处理任何其他依赖项一样

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


有人能帮我吗?或者谁有更好的解决方案?谢谢。

您不需要测试.Net是否能够从配置文件加载数据。
相反,试着集中精力测试你自己的逻辑

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

一路走来,你的班级也朝着新的方向发展

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


编辑:
将配置逻辑分离到另一个类中。大概是这样的:

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的问题。

就我个人而言,我会将您的静态构造函数插入到一个静态方法中,然后在静态块中执行该方法。

如果您从
(Web)ConfigurationManager.AppSettings阅读,这只是一个NameValueCollection,因此您可以将读取
ConfigurationManager.AppSettings
的代码直接替换为从任何NameValueCollection读取的代码

只需将实际的配置解析从静态ctor移到静态方法。静态ctor调用该静态方法并传递
ConfigurationManager.AppSettings
,但是您可以从测试代码调用该解析器方法,并验证配置解析,而无需实际接触文件或处理appdomains

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


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

我最近也遇到了同样的问题。唯一的区别是配置值来自数据库,而不是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]);
}
[测试]
public void TestConfigurationInstallaticConstructor()
{
//设置要测试的配置
// ...
//初始化静态构造函数
ReaderTypeInit();
//断言配置效果
// ...
//重置静态ctor以防止其他现有测试(可能取决于原始静态ctor)失败
ReaderTypeInit();
}
//辅助方法
私有void ReaderTypeInit()
{
typeof().TypeInitializer.Invoke(null,新对象[0]);
}

将该逻辑提取到非静态类中,并从cctor中调用它。现在你可以测试这个新类了。谢谢你的回复。但是我们使用了静态构造函数来避免每次调用时从配置值中读取值。我编写的单元测试不是测试.NET是否能够从配置文件加载数据,而是测试具有不同值的方法的行为。