单元测试依赖于会话变量的控制器

时间:2012-01-25 21:04:47

标签: asp.net-mvc unit-testing asp.net-mvc-3

我有一个依赖于Session变量的控制器。为了对该控制器进行单元测试,我提出了以下解决方案。它有效,但我想知道是否有更好/更清洁的方式。感谢

控制器

    public JsonResult UpdateStatus(ImageUpdateStatus imageUpdateStatus, SessionStateItemCollection sessionItems = null)
    {
        var data = new object();
        string status = null;

        ImageInfo imageInfo = new ImageInfo();
        IImageInfoServices svcImageInfo = new ImageInfoServicesRepository();
        imageInfo = svcImageInfo.GetImageByImageId(imageUpdateStatus.ImageId);

        IDeviceControlServices svcDevice = new DeviceControlServicesRespository();
        IPVSCommandServices svcPVSCmds = new PVSCommandServicesRespository();

        if (imageUpdateStatus.Task == "prep")
        {
            List<UpdateReasonForm> updateReasonForms;

            if (sessionItems != null)
            {
                updateReasonForms = sessionItems["UpdateReasonForms"] as List<UpdateReasonForm>;
            }
            else
            {
                updateReasonForms = Session["UpdateReasonForms"] as List<UpdateReasonForm>;
            }

            foreach (var item in updateReasonForms)
            {
                if (item.ImageId == imageInfo.ImageId)
                {
                    status = svcPVSCmds.PrepImage(imageInfo, item.NewVersion);
                }
            }

            data = new
            {
                status
            };
        }

        if (imageUpdateStatus.Task == "boot")
        {
            status = svcDevice.Boot(imageInfo.ImageId);

            data = new
            {
                status
            };
        }

        return this.Json(data, JsonRequestBehavior.AllowGet);
    }

单元测试

        [TestMethod()]
    public void UpdateStatusTest()
    {
        BuildController target = new BuildController(); // TODO: Initialize to an appropriate value
        ImageUpdateStatus imageUpdateStatus = new ImageUpdateStatus(); // TODO: Initialize to an appropriate value
        imageUpdateStatus.ImageId = 3;
        imageUpdateStatus.Task = "prep";
        UpdateReasonForm updateReasonForm = new UpdateReasonForm();
        updateReasonForm.ImageId = 3;
        updateReasonForm.NewVersion = "TestThis";

        List<UpdateReasonForm> updateReasonForms = new List<UpdateReasonForm>();
        updateReasonForms.Add(updateReasonForm);

        var sessionItems = new SessionStateItemCollection();
        sessionItems["UpdateReasonForms"] = updateReasonForms;

        JsonResult actual;
        actual = target.UpdateStatus(imageUpdateStatus, sessionItems);
    }

3 个答案:

答案 0 :(得分:3)

您可以像这样模拟会话状态,而不是将会话值作为参数传递:

How do you mock the session object collection using Moq

答案 1 :(得分:1)

您对Session有依赖性。您可以将代码移动到可测试的方法中,在方法级别注入依赖项。看起来你正走在这条道路上我只是将代码抽象为自己的方法,允许你测试功能,无论数据是否来自会话。

 public JsonResult UpdateStatusDependencyInjection(ImageUpdateStatus imageUpdateStatus, Dictionary<string, object> sessionValues)
        {
        var data = new object();
        string status = null;

        ImageInfo imageInfo = new ImageInfo();
        IImageInfoServices svcImageInfo = new ImageInfoServicesRepository();
        imageInfo = svcImageInfo.GetImageByImageId(imageUpdateStatus.ImageId);

        IDeviceControlServices svcDevice = new DeviceControlServicesRespository();
        IPVSCommandServices svcPVSCmds = new PVSCommandServicesRespository();

        if (imageUpdateStatus.Task == "prep")
        {
            List<UpdateReasonForm> updateReasonForms;

            if (sessionItems != null)
            {
                updateReasonForms = sessionItems["UpdateReasonForms"] as List<UpdateReasonForm>;
            }
            else
            {
                updateReasonForms = Session["UpdateReasonForms"] as List<UpdateReasonForm>;
            }

            foreach (var item in updateReasonForms)
            {
                if (item.ImageId == imageInfo.ImageId)
                {
                    status = svcPVSCmds.PrepImage(imageInfo, item.NewVersion);
                }
            }

            data = new
            {
                status
            };
        }

        if (imageUpdateStatus.Task == "boot")
        {
            status = svcDevice.Boot(imageInfo.ImageId);

            data = new
            {
                status
            };
        }

        return this.Json(data, JsonRequestBehavior.AllowGet);
    }

答案 2 :(得分:0)

http://codingsmith.co.za/a-better-way-of-working-with-httpcontext-session-in-mvc/

这是我对Session的接口包装器的实现。 它目前正在生产和工作正常,它注入我的控制器,但我可以在测试时手动使用其他一个实现