【发布时间】:2015-03-06 22:34:02
【问题描述】:
我有使用单例的代码(这恰好是针对网站的,所以单例的范围只有一个请求;每个请求都有自己的单例)。
我的代码(恰好位于 HttpModule 中)执行以下操作:
1 - 检查 Singleton 对象是否为空,如果是,则对其进行初始化。 2 - 按照以下方式更新此单例对象的属性:
if(A)
{
SingletonHolder.Current.X = Y;
}
else
{
SingletonHolder.Current.X = Z;
}
然后我想围绕这个方法进行一些单元测试来检查逻辑是否正确。假设我们需要以下 4 个测试:
- GivenMethodCall_WhenA_ThenXSetToY
- GivenMethodCall_WhenA_ThenXNotSetToZ
- GivenMethodCall_WhenNotA_ThenXSetToZ
- GivenMethodCall_WhenNotA_ThenXNotSetToY
这些测试在一次运行一个时运行良好,但是当在 VS2013 中使用 NUnit 测试运行器运行时,我们会遇到一些失败,因为每个测试都是并行运行的,并且被测方法正在更新同一个单例具有不同值的对象的属性。
有什么可以解决这个问题的模式的建议吗?
谢谢
格里夫
【问题讨论】:
-
一种使您的课程正确并发的模式。不使用单例的更好模式。无论如何,这就是您进行测试的原因
-
是否可以选择摆脱单例?那将是最好的事情。在请求开始时创建它并将其传递给需要它的方法。
-
我不清楚这个重要的细节:如果单例每个请求都是唯一的,为什么每个测试调用都不是唯一的?这里有什么区别?
-
这取决于测试的结构。无论如何,我假设 OP 是独立于 ASP.Net 本身进行测试的,因此,测试不是在 HTTP 请求的上下文中运行的。因此,如果没有在每个测试方法的开头和结尾显式设置和拆除 Singleton 对象,这将是预期的行为(除非您使用的是 xUnit ;))。
-
被测代码是 HttpApplication 的 BeginRequest 事件的 EventHandler。在这种方法中,我们创建了一个单例“上下文”类,它包含我们网页中的代码可能需要的所有内容(因此,站点、客户、缓存、跟踪器等信息)。丹尼尔,我很抱歉,我错了,Singleton 当然适用于 AppDomain 中的所有内容 - 我将自己与 HttpApplication 上的 Items Collection 混淆了(根据请求)。也许我需要在不同的 AppDomains 中运行每个测试(或者这有点过头了?)。
标签: unit-testing tdd automated-tests integration-testing