【发布时间】:2011-09-26 18:35:25
【问题描述】:
我最近实现了一个工作单元模式,作为一个环境,我们使用了更多的单元测试。目前,实现写入写入会话的会话助手。我如何对会话的这些方面进行单元测试?我应该制作存储库模式吗? (具有具体会话实现和具体模拟实现的存储库接口)这通常是如何完成的?
我知道可能有不止一种方法可以解决这个问题,但我只是在寻求一些建议。
【问题讨论】:
标签: c# unit-testing
我最近实现了一个工作单元模式,作为一个环境,我们使用了更多的单元测试。目前,实现写入写入会话的会话助手。我如何对会话的这些方面进行单元测试?我应该制作存储库模式吗? (具有具体会话实现和具体模拟实现的存储库接口)这通常是如何完成的?
我知道可能有不止一种方法可以解决这个问题,但我只是在寻求一些建议。
【问题讨论】:
标签: c# unit-testing
基本上有两种方法可以做到这一点。
假设您使用的是 .NET 3.5 或更高版本。更改您的实现以将 HttpSessionStateBase 对象作为构造函数参数,然后您可以模拟此实现 - 网上有一些关于如何执行此操作的教程。然后,您可以使用 IoC 容器在应用启动时将其连接起来,或者执行类似(穷人的依赖注入)之类的操作:
public class MyObjectThatUsesSession
{
HttpSessionStateBase _session;
public MyObjectThatUsesSession(HttpSessionStateBase sesssion)
{
_session = session ?? new HttpSessionStateWrapper(HttpContext.Current.Session);
}
public MyObjectThatUsesSession() : this(null)
{}
}
另外,可能更好和更灵活的设计是通过将您与会话的交互包装在另一个对象中来创建测试接缝。然后,您可以稍后将其更改为基于数据库、cookie 或缓存的实现。比如:
public class MyObjectThatUsesSession
{
IStateStorage _storage;
public MyObjectThatUsesSession(IStateStorage storage)
{
_storage= storage ?? new SessionStorage();
}
public MyObjectThatUsesSession() : this(null)
{}
public void DoSomethingWithSession()
{
var something = _storage.Get("MySessionKey");
Console.WriteLine("Got " + something);
}
}
public interface IStateStorage
{
string Get(string key);
void Set(string key, string data);
}
public class SessionStorage : IStateStorage
{
//TODO: refactor to inject HttpSessionStateBase rather than using HttpContext.
public string Get(string key)
{
return HttpContext.Current.Session[key];
}
public string Set(string key, string data)
{
HttpContext.Current.Session[key] = data;
}
}
然后您可以使用 Moq 为您的测试创建一个模拟 IStateStorage 实现或创建一个简单的基于字典的实现。
希望对您有所帮助。
【讨论】:
有点含糊的问题,但我仍然尝试为您提供一些想法。可能,您将能够稍微澄清您的问题。
您可以用模拟、间谍或假对象替换您的会话助手。因此,在完成工作单元后,您可以验证所有必要的数据是否已到达会话助手。在我看来,假的对象更可取,但我对你的案子了解得不够多。如何将这个假货传递给会话取决于您的设计。例如,会话助手可以在其构建期间传递到工作单元中。或者您可以使用您编写的存储库,但是您必须将存储库注入工作单元,并且可能创建额外的假存储库以返回假会话助手。其他解决方案也存在。
请注意,会话助手和会话本身之间的交互细节也应该单独进行单元测试。但是,如果您的会话助手是一个非常简单的对象,那么您可以测试该数据是否正确到达会话。因此,您的会话助手将被间接测试,您无需费心创建单独的测试。
【讨论】: