2013-02-20 14 views
5

ServiceStack/StructureMap/Ad. Kullanıyorum. Hizmet, ServiceStack.CacheAccess.ISession türü olan Session'a bir çağrı yapar. Ben Gidiyorum eminim - Oturum nesnesi boş iken şaşırmadım, AncakServiceStack ISession'ı Moq ve StructureMap kullanarak nasıl alay ediyorsunuz?

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

: ünite testleri için, ben MOQ kullanarak Mock nesne oluşturulur ve StructureMap yapılandırmasına eklendi bir adım dışarı. Session özelliğimi sahte bir nesne ile doldurmak için başka ne yapmam gerekir?

[DÜZENLE] İşte

Kodu sınamak için basit bir test senaryo. Basit istek/hizmet

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

baz testi sınıf ve MockSession sınıfları

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

Ve testler. Hatayı görüyorum nerede yorumları görmek. 1 & 2 sürümünün gerçekten çalışmasını beklemiyordum, ancak umduğum 3 sürümü.

[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"); 
    } 
} 
+0

I: Eğer AppHost.TestMode=true ServiceStack sizin IOC içinde kayıtlı IAuthSession, örneğin dönecektir set Aksi takdirde

[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")); } } } 

:

Sen mesela, Request.Items["__session"] bir örneğini kaydederek Oturum alay edebilir Bunun nedeni, birim testi yapıldığında, StructureMap adaptörünün düzgün bir şekilde yapılandırılmamış olması. Bunu nasıl yapacağınızdan emin değilsiniz ... –

+0

Test için tüm kodu gösterebilir misiniz? Yani, servisi nasıl aradığını görebilelim mi? – mythz

+0

Sorunu ve nasıl çözmeyi denediğimi gösteren kod eklendi. –

cevap

7

Birim testleri oluşturmaya çalışıyorsunuz gibi görünüyor, ancak Entegrasyon testini yaptığınız gibi bir AppHost kullanıyorsunuz. Bu previous answer for differences between the two ve docs on Testing'a bakın.

[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(); 
} 
+0

Yanıt için teşekkürler! ISessionFactory'yi manuel olarak doldurmadığım SS yöntemlerinden birini kullanarak hizmeti oluşturmak için * çalıştığımı düşünmeye çok odaklanmıştım. –

+0

np :) ServiceStack, basit temiz sınıflar ve arabirimlerle oldukça sıkı bir şekilde bağlanmış olduğundan, çoğu zaman en kolay şey işe yarayacaktır :) – mythz

+0

Harika çalıştı! StructureMap ile çalışmak için biraz değişti. –