如何使用Moq和StructureMap来模拟ServiceStack ISession?
我正在使用ServiceStack/StructureMap/Moq。该服务调用Session,这是类型ServiceStack.CacheAccess.ISession。单元测试,我创建使用起订量模拟对象,并把它添加到StructureMap配置:如何使用Moq和StructureMap来模拟ServiceStack ISession?
protected Mock<ISession> sessionMock = new Mock<ISession>();
ObjectFactory.Configure(
cfg =>
{
cfg.For<ISession>().Use(sessionMock.Object);
不过,我并不感到惊讶,当Session对象为空 - 我敢肯定,我离开走出一步。我还需要做什么才能用模拟对象填充我的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");
}
}
它看起来像你想创建单元测试,但像你伤口的集成测试你使用的是APPHOST。看到这个previous answer for differences between the two和docs on 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=true
ServiceStack将返回在你的国际奥委会注册的IAuthSession
,如:
[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();
}
感谢您的回应!我非常专注于思考我有*使用SS方法之一创建服务,我没有手动填写ISessionFactory。 – 2013-02-21 21:32:22
np :) ServiceStack几乎与简单的干净类和接口绑定在一起,所以大多数时候最简单的东西都可以工作:) – mythz 2013-02-21 21:41:21
工作也很棒!只需稍加改动即可使用StructureMap。 – 2013-02-21 22:05:27
我认为这是因为我没有在单元测试时正确配置StructureMap适配器。不知道该怎么做... – 2013-02-20 15:17:25
你可以显示所有的测试代码?即我们可以看到您如何致电该服务? – mythz 2013-02-20 23:30:37
添加了显示问题的代码以及我如何解决问题。 – 2013-02-21 16:10:54