0

我目前使用以下方法来创建表示会话变量的强类型对象。

public abstract class SessionController : Controller
{
    private const string SESSION_NAME = "UserSession";

    public SessionData SessionData
    {
        get
        {
            SessionData sessionData = (SessionData)Session[SESSION_NAME];

            if (sessionData != null)
            {
                return sessionData;
            }
            else
            {
                sessionData = new SessionData();
                Session[SESSION_NAME] = sessionData;

                return sessionData;
            }
        }
        set
        {
            Session[SESSION_NAME] = value;
        }
    }  
}

SessionData 是一个简单的对象,例如

[Serializable]
public class SessionData
{
    public String SessionId { get; set; }
    public Int64 UserId { get; set; }
    public String NameOfUser { get; set; }
}

创建新控制器时,我从 SessionController 派生它,这样我就可以对我的 SessionData 进行强输入访问。例如

public CityController : SessionController
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        ViewData.Model = _cityService.GetAll(SessionData.UserId);

        return View("Index");
    }
}

因此,我目前正在努力通过单元测试来解决这个问题。我尝试过的缩短版本是以下代码段

[SetUp]
public void SetUp()
{
    mocks = new MockRepository();
    _cityService = MockRepository.GenerateStub<ICityService>();
    _sesssionData = new SessionData { UserId = 1, SessionId = "1" };

    // First Approach
    controller = new CityController(_cityService);
    controller.Expect(p => p.SessionData).Return(_sesssionData);

    // Second Approach
    cctx = MockRepository.GenerateStub<ControllerContext>();
    cctx.Expect(p=>p.HttpContext.Session["UserSession"] as SessionData).Return(_sesssionData);
    controller.ControllerContext = cctx;
}

有没有人提示如何解决这个问题?

4

1 回答 1

1

如果您将 SessionData 属性设为虚拟,那么您的第一种方法可能会奏效:

// Arrange
var mocks = new MockRepository();
var cityService = MockRepository.GenerateStub<ICityService>();
var sesssionData = new SessionData { UserId = 1, SessionId = "1" };
var controller = mocks.PartialMock<CityController>(cityService);
controller.Expect(c => c.SessionData).Return(sessionData);
controller.Replay();

// Act
controller.Index();

//Assert
...

IMO 这种方法不是很好,因为 SUT(在这种情况下为 CityController 的被测对象 =>)正在使用 PartialMock 进行模拟。

于 2009-04-24T09:59:20.760 回答