数据访问,单元测试,依赖注入 [英] Data access, unit testing, dependency injection
问题描述
所以,这里是一个问题:数据访问类是静态的,这不允许模拟它,因此创建真正的单元测试。为了解决这个问题,我需要创建一个接口并在数据访问类中实现它。此外,我将不得不向业务逻辑类添加一个构造函数,该类接受该接口类型的参数。所以这意味着我将最终在应用程序Main()方法中创建数据访问类,有些东西告诉我这不是最好的方法(入门点应该知道一些数据访问的东西真的很好吗?更长的时间还是应该有几条链?我知道我可以使用一些IoC容器,但我认为这是太简单的应用程序来使用容器。
谢谢!
我需要创建一个接口并在数据访问类中实现它。此外,我将不得不向业务逻辑类添加一个构造函数
,该类将
接受该接口
类型的参数。所以这意味着我将在
应用程序Main()方法和
中创建
创建数据访问类,有些东西告诉我这不是最好的
方法(真的可以吗
入口点应该知道一些
数据访问的东西?如果链
更长或应该有
几条链?)
恰恰相反!至少从可测试性的角度来看,这种是最好的方法。
使您的业务逻辑层可测试的唯一方法是将其与您的数据访问层通过做你正在考虑的事情。
您的顶级应用程序是降级的地方 - 它是唯一需要知道具体数据访问类的组件。
如果链条长得多或有几条链,那没有什么大不了的(尽管如果这些链接失败,您可能希望考虑折叠一些应用程序层)。在 Model-View-Presenter
应用程序的视图
中考虑这个潜在的代码,其中 Presenter
依赖于一个 CustomerService
,它依赖于 Repository
和依赖关系一个 AccountingService
(这也取决于资源库
):
public $($)$ {pre>
public CustomerView(){
IRespository repository = new ConcreteRepository();
IAccountingService accountingService = new ConcreteAccountingService(repository);
ICustomerService customerService = new ConcreteCustomerService(accountingService,repository)
this._Presenter = new CustomerPresenter(customerService);
}
最后,如果没有依赖注入容器,则不需要使用想要(虽然其中有些是令人惊讶的轻量级) - 手动依赖注入工作正常,直到您在整个地方重新开始重复(或者想要在运行时配置依赖项)。
I've recently got a task to create a simple utility that allows to import data from a file with special format to the database. I've implemented console application with few classes(Program class operates with business logic class, business logic class in turn operates with data access class). Everything works ok, but now I'm thinking about creating some unit tests and refactoring application (I have not created real unit tests before, just a bunch of integration tests a long time ago, so I believe this application is perfect field for practicing).
So, here is the problem: the data access class has been made static, this doesn't allow to mock it and as a result create real unit tests. To fix this I need to create an interface and implement it in the data access class. Also I will have to add a constructor to the business logic class that will accept parameter of that interface type. So this means that I will end up creating data access class in the application Main() method and something tells me this not the best approach (is it really ok that the entry point should know about some data access things? what if the chain is much longer or there should be several chains?). I know I can use some IoC container, but I think this is too simple application to use containers.
Thanks!
I need to create an interface and implement it in the data access class. Also I will have to add a constructor to the business logic class that will accept parameter of that interface type. So this means that I will end up creating data access class in the application Main() method and something tells me this not the best approach (is it really ok that the entry point should know about some data access things? what if the chain is much longer or there should be several chains?)
On the contrary! This is the best approach, at least from a testability perspective.
The only way to make your business logic layer testable is to isolate it from your data access layer by doing exactly what you're contemplating.
Your top-level application is where the buck stops - it's the only component that should need to know what the concrete data access class is.
If the chain is much longer or there are several chains, that's no big deal (though you may want to consider collapsing some application layers if it gets out of hand). Consider this potential code in a Model-View-Presenter
app's View
, where the Presenter
has a dependency on a CustomerService
, which has a dependency on a Repository
and a dependency on an AccountingService
(which is also dependent on the Repository
):
public CustomerView() {
IRespository repository = new ConcreteRepository();
IAccountingService accountingService = new ConcreteAccountingService(repository);
ICustomerService customerService = new ConcreteCustomerService(accountingService, repository)
this._Presenter = new CustomerPresenter(customerService);
}
Finally, there's no need to use a dependency injection container if you don't want to (though some of them are surprisingly lightweight) - dependency injection by hand works fine until you start repeating yourself all over the place (or find you want to configure the dependencies at runtime).
这篇关于数据访问,单元测试,依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!