【问题标题】:Stub/Mock 2 levels down in a class存根/模拟 2 级在一个类中
【发布时间】:2013-12-16 09:28:06
【问题描述】:

我有一个无法测试的设置提供程序(企业遗留代码)。我正在尝试将设置提供程序包装在设置存储库中以减少不可测试代码的数量。因此,我们将不再有 20 个方法使用 Settings 提供程序,而是有 1 个。其余的实现 SettingsRepository 接口。

我在之后的测试中遇到了麻烦,这通常表明我做错了。

我希望你能帮助找出什么。

    public class SettingsRepository : ISettingsRepository
{
    public SettingsRepository() {Settings = Settings.Default; }
    public Settings Settings { get; set; }
}

public interface ISettingsRepository
{
    Settings Settings { get; set; }
}

我使用统一注入存储库。我从存储库中获取内容的方式如下:

_settingsRepository.Settings.SecureCache

所以这就是问题所在。我可以使用 nsubstitute 模拟/存根 SettingsRepository 接口,但实际上我需要做的是模拟“设置”以设置 SecureCache 的返回。

有没有办法在 nsubstitute 中“深度模拟”,所以我可以做类似的事情:

_settingsRepository.Settings.SecureCache.Returns("www.somepath.com");

目前“设置”为空,我没有可以在那里模拟的任何东西。

我的后备解决方案是直接在 SettingsRepository 上添加所有设置字段,但我希望避免这种情况,因为它只会将无法测试的代码移动到解决方案的其他位置。

【问题讨论】:

    标签: c# unit-testing mocking stub nsubstitute


    【解决方案1】:

    使用 NSubstitue(版本 1.5.0.0),您可以执行以下操作。您可以创建一个 Settings 实例(或者您甚至可以创建一个假实例),然后返回假 SecureCache,如下所示。

     public class SettingsRepository : ISettingsRepository {
        public SettingsRepository() { Settings = Settings.Default; }
        public Settings Settings { get; set; }
    }
    
    public interface ISettingsRepository {
        Settings Settings { get; set; }
    }
    
    public class Settings {
        public Settings Default { get; set; }
        public string SecureCache { get; set; }
    }
    
    [TestFixture]
    public class TestClass
    {
        [Test]
        public void Subject_Scenario_Expectation()
        {
            var repoStub = Substitute.For<ISettingsRepository>();
            repoStub.Settings.Returns(new Settings() { SecureCache = "www.somepath.com" });
    
            Assert.IsNotNull(repoStub.Settings);
            Assert.IsNotNull(repoStub.Settings.SecureCache);
        }
    }
    

    【讨论】:

    • 听起来我在正确的轨道上。您可以扩展“假实例”部分吗? Settings 是一个密封的类。感谢您的帮助
    • 很高兴你问:) 假实例是指真实实例的替代版本。例如,我可以从真实实例继承并创建自己的假版本。 FakeSettings 类:设置。然后你可以在你的单元测试中使用 FakeSettings。因为它是密封的,你不能继承。所以真实的实例会完成这项工作。正是我在代码中的内容。
    猜你喜欢
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 2011-08-01
    • 2011-12-26
    • 2010-09-22
    相关资源
    最近更新 更多