0

我有一个具有存储库层、DTO 服务层和 WebAPI 层的 webAPI 应用程序。WebAPI 调用 DTO 调用存储库。

我的存储库是这样开始的:

public class RepositoryService : IRepositoryService
    {
        private readonly DbContext _db;

        public RepositoryService(string connectionString)
        {
            _db = new DbContext(connectionString);
        }

        public RepositoryService()
        {
            _db = new DbContext();
        }

我的 DTO 服务是这样开始的:

public class DtoService : IDtoService
    {
        private readonly RepositoryService _repository;

        public DtoService(string connectionString)
        {
            _repository = new RepositoryService(connectionString);  
        }

        public DtoService()
        {
            _repository = new RepositoryService();   
        }

我的 DbContext 看起来像这样:

public DbContext() : base("name=TestConnection")
        {

        }

public DbContext(string connectionString) : base(connectionString)
        {

        }

到目前为止,这使我可以选择定义一个连接字符串,以便在运行应用程序进行测试时使用。

第一个问题: 这种方法看起来可以吗?

现在我已经到了我的 WebAPI 层,我不只是有一个控制器类。我有一堆不同的控制器。我正在考虑为每个控制器执行和实现这些构造函数,但必须有更好的方法来做到这一点。有些东西告诉我这是依赖注入发挥作用的地方,但我不确定。

我可以做这样的事情:

  1. 为每个控制器创建构造函数,就像我为上面的服务一样
  2. 在我的测试中,新建每个控制器的实例,例如

    var accountController = new AccountController(connectionStringForTesting)

但我知道这不切实际,所以...

第二个问题:实用的方法是什么样的?

4

2 回答 2

1

如果您对单元测试感兴趣,那么模拟数据库是一种很好的做法,因此您的测试不依赖于任何类型的 IO 或数据库。您可能希望将您DBContext隐藏在接口后面并使用任何模拟框架(例如Moq)来模拟请求的回调而不是传递连接字符串。

如果您对集成测试感兴趣,那么您只需要单独的数据库并且您的所有代码都可以保持不变。

于 2013-05-06T03:28:01.210 回答
0

为了使您的类可以很好地进行单元测试,注入所有依赖项是一种很好的做法,这样您就可以单独测试每个类。

在尝试这样做 - 它不会开箱即用,因为您需要连接您选择的容器中的依赖项,并且配置可能会有所不同,具体取决于您从哪里获取它,但我希望你会明白的。

 public DbContext(IConfig config) : base(config.ConnectionString)
 { 
 }

public interface IConfig
{
   string ConnectionString {get;}
}

public class RepositoryService : IRepositoryService
{
    private readonly DbContext _dbContext;

    public RepositoryService(IDbContext dbContext)
    {
        _dbContext = dbContext;
    }
}

public class DtoService : IDtoService
    {
        private readonly RepositoryService _repository;

        public DtoService(IRepositoryService repository)
        {
        }
}

完成所有这些之后,您将使用 Dima 建议的模拟框架 - 在 Rhino.Mocks 中,您将按照以下方式进行操作:

var config = MockRepository.GenerateStub<IConfig>();
config.Stub(c => c.ConnectionString).Return("yourConnectionString");

var dbContext = MockRepository<IDbContext>();

var controller = new YourController([mockDependency1], [mockDependency2]);

controller.[YourMethod]();
_dbContext.AssertWasCalled(dc => dc.[theMEthodYouExpectToHaveBeenCalled])
于 2013-05-06T19:43:05.963 回答