无法通过集成测试中的连接管理器访问 App.Config

Cannot Access App.Config via Connection Manager in Integration Tests

我已经围绕 ConnectionManager 创建了一个包装器 class。 class 有两种访问 AppSettings 和 ConnectionStrings 的方法。进行测试的原因是因为我有关于默认值的应用程序设置的逻辑。

我的项目是一个 class 库,它确实有一个带有连接字符串和应用程序设置的 App.config 文件。当尝试访问 ConfigurationManager 时,它 returns 两者都为 null。我正在使用 XUnit nuget 包 FluentAssertions 进行测试。我正在使用 ReSharper 作为我的测试运行器。

我已经阅读了几个关于单元测试和模拟的问题。这是一个集成测试。它旨在实际测试外部依赖性。

App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <clear />
    <add name="TestConnectionString" connectionString="Sample Connection String" />
  </connectionStrings>

  <appSettings>
    <add key="TestAppSetting" value="Sample App Setting"/>
  </appSettings>
</configuration>

包装纸Class(剪切)

public class ConfigurationRepositoryImpl : IConfigurationRepository {
    public string GetConnectionString(string key) {
        return ConfigurationManager.ConnectionStrings[key].ConnectionString;
    }

    public string GetValue(string key, string defaultValue) {
        return ConfigurationManager.AppSettings[key] ?? defaultValue;
    }
}

集成测试

using FluentAssertions;
using Xunit;

namespace MyIntegrationProject {
public class ConfigurationRepositoryTests {
    private static ConfigurationRepositoryImpl MakeRepo() {
        return new ConfigurationRepositoryImpl();
    }

    public class GetConnectionString {
        [Fact]
        public void GoodConnectionName_ReturnsExpectedValue() {
            // arrange
            //var repo = MakeRepo();
            var key = "TestConnectionString";
            var expected = "Sample Connection String";

            // act
            var test = System.Configuration.ConfigurationManager.ConnectionStrings[key].ConnectionString;
            //var test = repo.GetConnectionString(key);

            // assert
            test.Should()
                .Be(expected);
        }

    }
}}

为了在等待答案时让事情继续进行,我将此 class 变成了 Roy Osherove 在 The Art of Unit Testing 中所讨论的更多接缝。这肯定打破了集成测试的想法,但它确实让代码覆盖了测试。

包装纸Class(剪切)

public class ConfigurationRepositoryImpl : IConfigurationRepository {
    #region attributes
    private static NameValueConfigurationCollection _connectionString;
    private static NameValueConfigurationCollection _values;
    #endregion


    public string GetConnectionString(string key) {
        string retVal = null;

        if (_connectionString == null ||
            _connectionString.Count == 0) {
            retVal = ConfigurationManager.ConnectionStrings[key].ConnectionString;
        } else {
            retVal = _connectionString[key].Value;
        }

        return retVal;
    }

    public string GetValue(string key, string defaultValue) {
        string retVal = null;

        if (_values == null ||
            _values.Count == 0) {
            retVal = ConfigurationManager.AppSettings[key] ?? defaultValue;
        } else {
            retVal = _values[key].Value ?? defaultValue;
        }

        return retVal;
    }

    public static void ResetConnectionStrings() {
        _connectionString = null;
    }

    public static void ResetValues() {
        _values = null;
    }

    public static void SetConnecitonString(string key, string connectionString) {
        if (_connectionString == null) {
            _connectionString = new NameValueConfigurationCollection();
        }

        _connectionString.Add(new NameValueConfigurationElement(key, connectionString));
    }

    public static void SetValue(string name, string value) {
        if (_values == null) {
            _values = new NameValueConfigurationCollection();
        }

        _values.Add(new NameValueConfigurationElement(name, value));
    }
}

更新测试

public class ConfigurationRepositoryTests {
    private static ConfigurationRepositoryImpl MakeRepo() {
        return new ConfigurationRepositoryImpl();
    }

    public class GetConnectionString {
        [Fact]
        public void GoodConnectionName_ReturnsExpectedValue() {
            // arrange
            var repo = MakeRepo();
            var key = "TestConnectionString";
            var expected = "Sample Connection String";

            // act
            ConfigurationRepositoryImpl.SetConnecitonString("TestConnectionString", "Sample Connection String");

            var test = repo.GetConnectionString(key);

            ConfigurationRepositoryImpl.ResetConnectionStrings();

            // assert
            test.Should()
                .Be(expected);
        }

        [Fact]
        public void BadConnectionName_ThrowsNullReferenceException() {
            // arrange
            var repo = MakeRepo();
            var key = "BadKeyName";

            // act
            Action act = () => {
                             repo.GetConnectionString(key);
                         };

            // assert
            act.Should()
               .Throw<NullReferenceException>();
        }
    }

    public class GetValue {
        [Fact]
        public void GoodKey_ReturnsExpectedValue() {
            // arrange
            var repo = MakeRepo();
            var key = "TestAppSetting";
            var expected = "Sample App Setting";

            // act
            ConfigurationRepositoryImpl.SetValue("TestAppSetting", "Sample App Setting");

            var test = repo.GetValue(key, null);

            ConfigurationRepositoryImpl.ResetValues();

            // assert
            test.Should()
                .Be(expected);
        }

        [Fact]
        public void BadKeyWithNullDefaultValue_ReturnsNull() {
            // arrange
            var repo = MakeRepo();
            var key = "BadKeyName";

            // act
            var test = repo.GetValue(key, null);

            // assert
            test.Should()
                .BeNull();
        }

        [Fact]
        public void BadKeyWithGoodDefaultValue_ReturnsDefaultValue() {
            // arrange
            var repo = MakeRepo();
            var key = "BadKeyName";
            var defaultValue = "Good Value";
            var expected = "Good Value";

            // act
            var test = repo.GetValue(key, defaultValue);

            // assert
            test.Should()
                .Be(expected);
        }
    }
}