使用XML作为数据源的单元测试存储库

时间:2013-10-23 19:49:17

标签: c# asp.net-mvc unit-testing tdd

我是一个单位测试菜鸟,并努力寻找一种测试我的存储库的好方法。我创建了一个CustomConfigurationManager来加载我的Custom.Config值。但无法弄清楚如何测试它们。

我的问题是

  1. 如何测试GetUserById()
  2. 中的代码
  3. 如何测试CustomConfigurationManager()
  4. 这是我正在尝试测试的存储库:

    public class UserRepository : IUserRepository
    {
        public User GetUserById(string id)
        {
            return CustomConfigurationManager.CustomConfig.Users.FirstOrDefault(u => u.UserId == id);
        }
    }
    
    
    public class CustomConfigurationManager
    {
        public static Configs CustomConfig
        {
            get
            {
                return CustomConfigLoader.LoadConfig<Configs>();
            }
        }
    }
    
    internal sealed class ConfigLoader
    {
        public static T LoadConfig<T>() where T : class
        {
            ...
    
            return LoadFromXML<T>();
        }
    }
    

    和XML

     <users>
        <user id="Foo" name="Bar" ... />
        ...
    </users>
    

    我粘贴的代码已修改,不是真正的代码。这只是一个例子。

1 个答案:

答案 0 :(得分:3)

我相信很多人会指出,从精确的意义上说,如果你正在阅读一个文件,那么它不是一个单元测试。实际上,你应该以更宽松的方式测试类似的东西,或找到伪造它的方法。

一个可以帮助你的小费:

public class UserRepository : IUserRepository
{
    public Configs CustomConfig {get;set;}
    public User GetUserById(string id)
    {
        return CustomConfig.Users.FirstOrDefault(u => u.UserId == id);
    }
}

这个想法是通过注入它(可能只在构造函数中),你可以在不读取文件的情况下测试它。这称为DI(依赖注入),通常最好用接口完成。

您的CustomConfigurationManager很难测试,因为它调用属性中的另一个静态方法;你可能只是不使用它。这是一个额外的复杂性,它隐藏了细节,但也隐藏了依赖,这是你永远不想做的。

如果没有InternalsVisibleTo,你无法真正测试ConfigLoader,但我认为这也是不好的做法。这个类是否需要密封?

尝试将您的设计集中在使方法工作而不假设可能的特定实现。如果你发现自己传递了太多东西,你可能需要一个新的课程。如果你发现自己一次做了太多事情,你可能需要更多的方法。