简体   繁体   English

单元测试 - Session object?

[英]Unit Testing - Session object?

I have recently Implemented a unit of work pattern, and as an environment we are using more unit testing.我最近实现了一个工作单元模式,作为一个环境,我们正在使用更多的单元测试。 Currently the implementation writes into a session helper that writes to session.目前,实现写入 session 助手,该助手写入 session。 How do I unit test these aspects in regard to the session?我如何对 session 的这些方面进行单元测试? Should I make a repository pattern?我应该制作存储库模式吗? (repository interface with concrete session implementation and concrete mock implementation) How is this normally done? (具有具体 session 实现和具体模拟实现的存储库接口)这通常是如何完成的?

I know there is probably more than one way of approaching this, but I am just looking for some advice.我知道可能有不止一种方法可以解决这个问题,但我只是在寻找一些建议。

There are basically two ways of doing this.基本上有两种方法可以做到这一点。

Assuming you are using .NET 3.5 or up.假设您使用的是 .NET 3.5 或更高版本。 Change your implementation to take the HttpSessionStateBase object as a constructor parameter, you can then mock this implementation - there's a few tutorials online on how to do this.更改您的实现以将 HttpSessionStateBase object 作为构造函数参数,然后您可以模拟此实现 - 网上有一些关于如何执行此操作的教程。 You can then use an IoC container to wire this up at app start or do something like (poor man's dependency injection):然后,您可以使用 IoC 容器在应用程序启动时将其连接起来,或者执行类似的操作(穷人的依赖注入):

public class MyObjectThatUsesSession
{
    HttpSessionStateBase _session;

    public MyObjectThatUsesSession(HttpSessionStateBase sesssion)
    {
         _session = session ?? new HttpSessionStateWrapper(HttpContext.Current.Session);
    }

    public MyObjectThatUsesSession() : this(null)
    {}
}

Alternatively, and probably a bit better and more flexible design would be to create a test seam by wrapping your interaction with session in another object.或者,可能更好和更灵活的设计是通过将您与 session 的交互包装在另一个 object 中来创建测试接缝。 You could then change this to a database, cookie or cache based implementation later.然后,您可以稍后将其更改为基于数据库、cookie 或缓存的实现。 Something like:就像是:

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;
    }
}

You can then use Moq to create a mock IStateStorage implementation for your tests or create a simple dictionary based implementation.然后,您可以使用 Moq 为您的测试创建一个模拟 IStateStorage 实现或创建一个简单的基于字典的实现。

Hope that helps.希望有帮助。

Somewhat vague question, but I still try to get you some ideas.有点模糊的问题,但我仍然试图给你一些想法。 Probably, you'll be able to clarify your question a bit.可能,您将能够稍微澄清您的问题。

You can substitute your session helper with mock, spy or fake object.您可以用模拟、间谍或假 object 替换您的 session 助手。 So after finishing unit of work you can verify that all necessary data reached session helper.因此,在完成工作单元后,您可以验证所有必要的数据是否已到达 session 助手。 In my opinion fake object is preferable, but I do not know enough details about your case.在我看来,假的 object 更可取,但我对你的情况不太了解。 How to deliver this fake to session depends on your design.如何将这个假货运送到 session 取决于您的设计。 Session helper can be passed into unit of work during its construction, for instance.例如,Session 助手可以在其构建期间传递到工作单元中。 Or you can use repository as you've written, but then you must inject repository into unit of work and probably create additional fake repository to return fake session helpers.或者您可以使用您编写的存储库,但是您必须将存储库注入工作单元并可能创建额外的假存储库以返回假 session 帮助程序。 Other solutions also exist.也存在其他解决方案。

Note that details of interaction between session helper and session itself also should be separately unit tested.请注意,session 助手和 session 本身之间的交互细节也应该单独进行单元测试。 But if your session helper is a very simple object then you can test that data correctly reach session.但是如果您的 session 助手是一个非常简单的 object 那么您可以测试该数据是否正确到达 session。 Thus, your session helper will be tested indirectly and you'll need not bother with creating separate test.因此,您的 session 助手将被间接测试,您无需费心创建单独的测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM