0

使用 C# 我正在尝试对控制器操作进行单元测试,并确定它们返回所需的时间。我正在使用 VS2012 Ultimate 中内置的单元测试框架。

不幸的是,我也试图围绕 TestContext 以及如何使用它。

一些示例代码(我的控制器操作):

[HttpPost]
public JsonResult GetUserListFromWebService()
{
    JsonResult jsonResult = new JsonResult();
    WebService svc = new WebService();
    jsonResult.Data = svc.GetUserList(User.Identity.Name);
    return jsonResult;
}

当我尝试对此进行单元测试时, User.Identity.Name 为空,因此会引发异常。我当前的单元测试代码如下所示:

[TestClass]
public class ControllerAndRepositoryActionTests {
    public TestContext testContext { get; set; }
    private static Repository _repository;
    private username = "domain\\foobar";
    private static bool active = true;

    [ClassInitialize]
    public static void MyClassInitialize(TestContext testContext)
    {
        _repository = new WebServiceRepository();
    }

    #region Controller method tests
    [TestMethod]
    public void GetUserListReturnsData() 
    {
        Controller controller = new Controller();
        var result = controller.GetUserListFromWebService();
        Assert.IsNotNull(result.Data);
    }
    #endregion

    #region service repository calls - with timing
    [TestMethod]
    public void GetUserListTimed()
    {
        testContext.BeginTimer("Overall"); 
        var results = _repository.GetUserList(username, active);
        foreach (var result in results)
        {
            Console.WriteLine(result.UserID);
            Console.WriteLine(result.UserName);
        }
        testContext.EndTimer("Overall");
    }
    #endregion 
}

我可以使用 TestContext 设置最终将在 GetUserListFromWebService 调用中使用的 User.Identity 吗?

如果可以的话,分配 TestContext 的公认方式是什么?当我在 MyClassInitialize 中将它作为参数获取时,我是设置我的成员变量,还是应该以某种方式将它作为参数传递给 TestMethods?

我是否完全错过了重点,我应该使用其他一些模拟框架吗?

4

1 回答 1

0

为了使这个测试有效,我应该改变你班级的签名。因为您不能为您的类 Webservice 创建存根或模拟,因为您是在方法中创建它。

class YourClass
{
   private readeonly WebService _ws;
   public YourClass(WebService ws)
   {
       _ws=ws;
   }

   [HttpPost]
   public JsonResult GetUserListFromWebService()
   {
       JsonResult jsonResult = new JsonResult();
       jsonResult.Data = _ws.GetUserList(User.Identity.Name);
       return jsonResult;
   }
}

现在,您可以在测试中轻松地使用 Moq 或其他框架模拟 WebService 类。为了使它更容易,您应该为实现 GetUserList() 方法的类 WebService 创建一个接口;

并模拟 User.Identy

public SomeController CreateControllerForUser(string userName) 
{
    var mock = new Mock<ControllerContext>();
    mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
    mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

    var controller = new SomeController();
    controller.ControllerContext = mock.Object;

    return controller;
}

或阅读这篇博文http://weblogs.asp.net/rashid/

于 2013-10-10T21:13:26.450 回答