2013-02-09 12 views
7

ho questo servizio:Unit Test HTTPRequest intestazioni con ServiceStack

public class PlayerService : Service 
{ 
    public IPlayerAppService PlayerAppService { get; set; } 

    public PlayerService (IPlayerAppService service) 
    { 
     if (service == null) 
      throw new ArgumentException ("Service null"); 

     PlayerAppService = service; 
    } 

    public object Post (PlayerDTO request) 
    { 
     var newPlayer = new PlayerResponse() 
     { 
      Player = PlayerAppService.SendPlayerLocation(request.Position.Latitude, request.Position.Longitude) 
     }; 

     return new HttpResult (newPlayer) 
     { 
      StatusCode = System.Net.HttpStatusCode.Created, 
      Headers = 
      { 
       { HttpHeaders.Location, base.Request.AbsoluteUri.CombineWith(newPlayer.Player.Id.ToString()) } 
      } 
     }; 
    } 
} 

ho verificato manualmente che la posizione e la risposta sembra corretto dai miei implementazioni di questo servizio. Mi piacerebbe capire come testare questa unità però. Ho scritto un test come questo:

[TestFixture] 
public class PlayerServiceTests 
{ 
    AppHost appHost; 

    [TestFixtureSetUp] 
    public void TestFixtureSetUp() 
    { 
     appHost = new AppHost(); 
     appHost.Init(); 
     appHost.Start ("http://localhost:1337/"); 
    } 

    [TestFixtureTearDown] 
    public void TestFixtureTearDown() 
    { 
     appHost.Dispose(); 
     appHost = null; 
    } 

    [Test] 
    public void NewPlayer_Should_Return201AndLocation() 
    { 
     // Arrange 
     PlayerService service = new PlayerService (appHost.TryResolve<IPlayerAppService>()); 

     // Act 
     HttpResult response = (HttpResult)service.Post (It.IsAny<PlayerDTO>()); 

     // Assert 
     Assert.NotNull (response); 
     Assert.AreEqual(HttpStatusCode.Created, response.StatusCode); 
     Assert.AreEqual(response.Response.ToDto<PlayerResponse>().Player.Id.ToString(), response.Headers.Where(x=> x.Key == HttpHeaders.Location).SingleOrDefault().Value); 
    } 
} 

La base.Richiedi quando viene eseguito il test dell'unità. Hai qualche suggerimento su come posso popolare questo dal mio test unitario?

+0

Lingua? C#? – Dukeling

+0

Sì :) Sviluppato in MonoDevelop. –

+2

Aggiunto tag appropriato. – Dukeling

risposta

12

Si sta utilizzando un HttpListener self-hosting come si farebbe per un test di integrazione, ma non si sta eseguendo il test di integrazione.

un test di integrazione sarà simile:

[Test] 
public void NewPlayer_Should_Return201AndLocation() 
{ 
    var client = new JsonServiceClient("http://localhost:1337/"); 
    client.LocalHttpWebResponseFilter = httpRes => { 
     //Test response headers... 
    }; 

    PlayerResponse response = client.Post(new Player { ... }); 
} 

caso contrario, se si vuole fare un test di unità che non è necessario un AppHost e può solo verificare la classe PlayerService come qualsiasi altra classe C#, iniettando tutto le dipendenze e il contesto di richiesta fittizio di cui ha bisogno.

[Test] 
public void NewPlayer_Should_Return201AndLocation() 
{ 
    var mockCtx = new Mock<IRequestContext>(); 
    mockCtx.SetupGet (f => f.AbsoluteUri).Returns("localhost:1337/player"); 

    PlayerService service = new PlayerService { 
     MyOtherDependencies = new Mock<IMyOtherDeps>().Object, 
     RequestContext = mockCtx.Object, 
    }; 

    HttpResult response = (HttpResult)service.Post(new Player { ... }); 

    //Assert stuff.. 
} 
+0

Ahh! Non mi è venuto in mente che potevo iniettare il RequestContext come questo nuovo xService {RequestContext = mockCtx.Object}; Grazie! –

+0

Nota: AbsoluteUri è di sola lettura, quindi SetupProperty non funzionerebbe in questo modo. –

+0

Sono stato in grado di impostare la proprietà in questo modo: mockCtx.SetupGet (f => f.AbsoluteUri) .Returns ("http: // localhost: 1337/player"); –