5

ServiceStack / StructureMap / Moq を使用しています。このサービスは、ServiceStack.CacheAccess.ISession タイプの Session を呼び出します。単体テストのために、Moq を使用して Mock オブジェクトを作成し、それを StructureMap 構成に追加しました。

protected Mock<ISession> sessionMock = new Mock<ISession>();
ObjectFactory.Configure(
    cfg =>
       {
           cfg.For<ISession>().Use(sessionMock.Object);

ただし、Session オブジェクトが null だったときは驚きませんでした。手順を省略していると確信しています。Session プロパティをモック オブジェクトで埋めるには、他に何をする必要がありますか?

[編集] 簡単なテスト シナリオを次に示します。

テストするコード。簡単な依頼・サービス

[Route("getKey/{key}")]
public class MyRequest:IReturn<string>
{
    public string Key { get; set; }
}

public class MyService:Service
{
    public string Get(MyRequest request)
    {
        return (string) Session[request.Key];
    }
}

基本テスト クラスと MockSession クラス

// test base class
public abstract class MyTestBase : TestBase
{
    protected IRestClient Client { get; set; }

    protected override void Configure(Container container)
    {
        // this code is never reached under any of my scenarios below
        container.Adapter = new StructureMapContainerAdapter();
        ObjectFactory.Initialize(
            cfg =>
                {
                    cfg.For<ISession>().Singleton().Use<MockSession>();
                });
    }
}

public class MockSession : ISession
{
    private Dictionary<string, object> m_SessionStorage = new Dictionary<string, object>();

    public void Set<T>(string key, T value)
    {
        m_SessionStorage[key] = value;
    }

    public T Get<T>(string key)
    {
        return (T)m_SessionStorage[key];
    }

    public object this[string key]
    {
        get { return m_SessionStorage[key]; }
        set { m_SessionStorage[key] = value; }
    }
}

そしてテスト。失敗が見られる場所については、コメントを参照してください。バージョン 1 と 2 が機能するとは思っていませんでしたが、バージョン 3 が機能することを期待していました。

[TestFixture]
public class When_getting_a_session_value:MyTestBase
{
    [Test]
    public void Test_version_1()
    {
        var session = ObjectFactory.GetInstance<MockSession>();
        session["key1"] = "Test";
        var request = new MyRequest {Key = "key1"};
        var client = new MyService();  // generally works fine, except for things like Session
        var result = client.Get(request);  // throws NRE inside MyService
        result.ShouldEqual("Test");
    }

    [Test]
    public void Test_version_2()
    {
        var session = ObjectFactory.GetInstance<MockSession>();
        session["key1"] = "Test";
        var request = new MyRequest {Key = "key1"};
        var client = ObjectFactory.GetInstance<MyService>();
        var result = client.Get(request);  // throws NRE inside MyService
        result.ShouldEqual("Test");
    }
    [Test]
    public void Test_version_3()
    {
        var session = ObjectFactory.GetInstance<MockSession>();
        session["key1"] = "Test";
        var request = new MyRequest {Key = "key1"};
        var client = CreateNewRestClient();
        var result = client.Get(request);  // throws NotImplementedException here
        result.ShouldEqual("Test");
    }
}
4

1 に答える 1

9

単体テストを作成しようとしているようですが、統合テストを作成したように AppHost を使用しています。この2 つの違いとTestingのドキュメントについては、この前の回答を参照してください。

にインスタンスを登録することで、セッションをモックできますRequest.Items["__session"]。例:

[Test]
public void Can_mock_IntegrationTest_Session_with_Request()
{
    using (new BasicAppHost(typeof(MyService).Assembly).Init())
    {
        var req = new MockHttpRequest();
        req.Items[SessionFeature.RequestItemsSessionKey] = 
            new AuthUserSession {
                UserName = "Mocked",
            };

        using (var service = HostContext.ResolveService<MyService>(req))
        {
            Assert.That(service.GetSession().UserName, Is.EqualTo("Mocked"));
        }
    }
}

それ以外の場合、AppHost.TestMode=trueServiceStackを設定するIAuthSessionと、IOC に登録されているが返されます。

[Test]
public void Can_mock_UnitTest_Session_with_IOC()
{
    var appHost = new BasicAppHost
    {
        TestMode = true,
        ConfigureContainer = container =>
        {
            container.Register<IAuthSession>(c => new AuthUserSession {
                UserName = "Mocked",
            });
        }
    }.Init();

    var service = new MyService {
        Request = new MockHttpRequest()
    };
    Assert.That(service.GetSession().UserName, Is.EqualTo("Mocked"));

    appHost.Dispose();
}
于 2013-02-21T21:10:30.583 に答える