应用程序级别和请求级别IOC容器存在的测试系统
【腾讯云】亏本大甩卖,服务器4核16G 1年370元(带宽12M,系统盘120GB SSD盘,月流量2000GB)!!!!!!
云产品 配置 价格
服务器 1核2G,带宽5M,系统盘50GB SSD盘,月流量500GB 38元/年
MySQL 1核1G 19元/年
服务器 16核32G,带宽18M,系统盘250GB SSD盘,月流量5000GB 1197元/年
点我进入腾讯云,查看更多详情

My team is in the process of developing a system where we're using Unity as our IoC container; and to provide NHibernate ISessions (Units of work) over each HTTP Request, we're using Unity's ChildContainer feature to create a child container for each request, and sticking the ISession in there.

We arrived at this approach after trying others (including defining per-request lifetimes in the container, but there are issues there) and are now trying to decide on a unit testing strategy.

Right now, the application-level container itself is living in the HttpApplication, and the Request container lives in the HttpContext.Current. Obviously, neither exist during testing.

The pain increases when we decided to use Service Location from our Domain layer, to "lazily" resolve dependencies from the container. So now we have more components wanting to talk to the container.

We are also using MSTest, which presents some concurrency dilemmas during testing as well.

So we're wondering, what do the bright folks out there in the SO community do to tackle this predicament?

How does one setup an application that, during "real" runtime, relies on HTTP objects to hold the containers, but during test has the flexibility to build-up and tear-down the containers consistently, and have the ServiceLocation bits get to those precise containers.

I hope the question is clear, thanks!


Thanks for the replies. I agree that using Service Location is not the optimal approach - but it does seem necessary for this situation. The scenario is that we need our Entities to resolve dependencies, on-demand, only when needed - for business rule validation. Forcing all our entities, on being materialized by NHibernate, to undergo constructor injection, doesn't seem appropriate, at a minimum for performance reasons.

We're considering a solution where the containers are stored either in the HttpApplication/HttpContext at real runtime, and in static/ThreadStatic fields during test. StructureMap has a similar approach baked-in. Any thoughts on this kind of solution? Thanks!

Also, this isn't necessarily integration testing (although it may play into that too). For example, we want to unit-test a particular entity's business rule behavior--during which this scenario will unfold.

I am definitely open to the Http object abstractions - I've used them and loved them in MVC; how can one get them going outside of MVC?

#0

DI Containers should not be necessary during unit testing. Rather, a DI Container is used at application startup time to resolve the application's dependency graph, and then get out of the way.

However, it sounds like you have applied the Service Locator anti-pattern, and you are now feeling the pain of that. Unfortunately, there's no easy way out of this.

You obviously can't rely on the real HTTP Context during unit testing, as it will not be available to you in that environment, so you will need to hide them away behind interfaces. If you are using .NET 3.5 SP1, you might be able to use the abstractions introduced in System.Web.Abstractions, but otherwise, you can extract some yourself.

Once you have introduced these Seams into your system, you can use proper Dependency Injection (preferably Constructor Injection) to inject them into your consuming classes.

In any case, following Test-Driven Development can very effectively prevent this type of tight coupling from being introduced in the first place.

推荐文章

在一个可执行文件中使用iPhoneOS3.0功能(如果可用)和2.1功能(如果不可用)

在一个可执行文件中使用iPhoneOS3.0功能(如果可用)和2.1功能(如果不可用)

推荐文章

SSIS XML配置文件位置

SSIS XML配置文件位置

推荐文章

如何快速找到向量和的最大元素?

如何快速找到向量和的最大元素?

推荐文章

如何找到互补标签?

如何找到互补标签?

推荐文章

我应该将数据库项目放在TFS中的哪个位置?

我应该将数据库项目放在TFS中的哪个位置?

推荐文章

在MySQL中保存使用触发器删除记录的用户的用户ID

在MySQL中保存使用触发器删除记录的用户的用户ID

推荐文章

SQLServer CASE表达式-短路评估?

SQLServer CASE表达式-短路评估?

推荐文章

如何限制Rails路由文件中的资源格式

如何限制Rails路由文件中的资源格式

推荐文章

确定HTML元素可见性服务器端

确定HTML元素可见性服务器端

推荐文章

黑莓用户代理

黑莓用户代理

推荐文章

需要Javascript Regex Replace来用

需要Javascript Regex Replace来用

推荐文章

VBA中的ShellExecuteEx

VBA中的ShellExecuteEx

推荐文章

在ASP.Net MVC控制器中查看每个条件

在ASP.Net MVC控制器中查看每个条件

推荐文章

使用textmate重构rails应用程序时如何查找引用?

使用textmate重构rails应用程序时如何查找引用?

推荐文章

使用SPI加载时消失jar条目

使用SPI加载时消失jar条目

推荐文章

在C中使用“Type”对象进行类型转换#

在C中使用“Type”对象进行类型转换#