我想为Web服务编写单元测试.我创建我的测试项目,引用我的web项目(不是服务引用,程序集引用),然后编写一些代码来测试Web服务 - 它们工作正常.但是,有一些服务可确保用户使用登录Web应用程序HttpContext.Current.User.Identity.IsAuthenticated.
在测试的上下文中,没有HttpContext这样的东西,所以测试总是失败.这些Web服务应该如何进行单元测试?
我看到很多关于HttpSessionState和asp.net MVC的讨论.我正在尝试为asp.net应用程序编写测试,并想知道是否有可能模拟HttpSessionState,如果是这样,怎么样?
我目前正在使用Rhino Mocks和Nunit
我从这里的示例设置了这个模拟会话对象:如何MOQ索引属性
/// <summary>
/// HTTP session mockup.
/// </summary>
internal sealed class HttpSessionMock : HttpSessionStateBase
{
private readonly Dictionary<string, object> objects = new Dictionary<string, object>();
public override object this[string name]
{
get { return (objects.ContainsKey(name)) ? objects[name] : null; }
set { objects[name] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
一些示例代码产生错误...
var mockSession = new HttpSessionMock();
var keys = mockSession.Keys;
Run Code Online (Sandbox Code Playgroud)
错误:未实现方法或操作.
我需要实现Keys属性,但不能创建KeysCollection对象.
做这个的最好方式是什么?
编辑:[解决方案]
我最终根据给出的答案更改了HttpSessionMock.这就是我最终的结果.(我还添加了对System.Linq的引用).
internal sealed class HttpSessionMock : HttpSessionStateBase
{
private readonly NameValueCollection objects = new NameValueCollection();
public …Run Code Online (Sandbox Code Playgroud) 我正在测试的特定类依赖于HttpSessionState对象.
HttpSessionState类没有公共构造函数.被测试的类仅将此对象用作NameValue存储.该类在ASMX Web服务中用于返回特定方法的信息.
我正在考虑在HttpSessionState类周围创建一个Facade,我可以在测试中提供Dictionary <string,string>而不是Session对象.
这是一个好主意还是标准做法?
我已经阅读了许多关于模拟会话对象或使用假对象的博客和评论,但我仍然无法将这些答案翻译成我自己的代码。
这是我的 UserController 的索引操作,它使用依赖注入将 IUserRepository 注入构造函数:
// GET: User
public ActionResult Index()
{
User user = (User) Session["CurrentUser"];
if (user != null) {
if(_repository.UserHasAdminAcces(user))
return View(_repository.GetAllUsers().ToList());
return RedirectToAction("DisplayErrorPage", "Error", new { errorMessage = "You have to be an Admin to enter this part" });
}
return RedirectToAction("Login");
}
Run Code Online (Sandbox Code Playgroud)
我的测试方法目前看起来像这样:
public void TestIndexForValidUser()
{
var mock = new Mock<IUserRepository>();
mock.Setup(x => x.UserHasAdminAcces(It.IsAny<User>())).Returns(true);
UserController target = new UserController(mock.Object);
// create mock HttpContext
var context = new Mock<ControllerContext>();
target.ControllerContext = context.Object;
var result …Run Code Online (Sandbox Code Playgroud) asp.net ×3
unit-testing ×3
c# ×2
rhino-mocks ×2
asp.net-mvc ×1
httpcontext ×1
nunit ×1
session ×1