2015-10-22 14 views
8

Ho la seguente metodo nella mia classe BaseApiController:SingleResult e unit testing

public virtual HttpResponseMessage GetById(int id) 
{ 
    var entity = repository.GetById(id); 

    if (entity == null) 
    {     
    var message = string.Format("No {0} with ID = {1}", GenericTypeName, id); 
    return ErrorMsg(HttpStatusCode.NotFound, message); 
    } 

    return Request.CreateResponse(HttpStatusCode.OK, SingleResult.Create(repository.Table.Where(t => t.ID == id))); 
} 

sto usando SingleResult per la richiesta OData (perché $expand per la singola entità non funziona se non creo SingleResult).
Ma ora ho problemi con UnitTests di questo metodo su controller concreto (ad esempio AddressApiController). Ho sempre trovato NULL nel totale:

[TestMethod] 
public void Get_By_Id() 
{ 
    //Arrange 
    var moq = CreateMockRepository(); 
    var controller = new AddressApiController(moq); 
    controller.Request = new HttpRequestMessage() 
    controller.Request.SetConfiguration(new HttpConfiguration()) 
    // Action 
    HttpResponseMessage response = controller.GetById(1); 
    var result = response.Content.ReadAsAsync<T>().Result; 

    // Accert 
    Assert.IsNotNull(result); 
} 

ho controllato ed eseguire il debug GetById() e scopro che repository.Table.Where(t => t.ID == id)) ritorno valore appropriato, ma dopo SingleResult.Create sto ottenendo NULL.

Come posso risolvere questo problema? Come posso leggere il contenuto da SingleResult o usare qualcos'altro?

+0

si fa a testare controller di base? Si prega di mostrare più pieno esempio del tuo codice. – Andrei

+0

No, sto testando il controller concreto. Ho aggiornato la domanda. – Marusyk

+0

Tutto funziona correttamente prima di aggiungere 'SingleResult.Create' – Marusyk

risposta

0

ho creato estensioni:

public static class HttpResponseMessageExtensions 
    { 
     public static IQueryable<T> ContentToQueryable<T>(this HttpResponseMessage response) where T : BaseEntity 
     { 
      var objContent = response.Content as ObjectContent; 
      return objContent?.Value as IQueryable<T>; 
     } 

     public static T ContentToEntity<T>(this HttpResponseMessage response) where T : BaseEntity 
     { 
      var objContent = response.Content as ObjectContent; 
      return objContent?.Value as T; 
     } 
    } 

e poi:

var result = response.ContentToEntity<T>(); 
0

non ho avuto la possibilità di mock up un'API, ma dalla documentazione qui:

Ecco alcune regole per le firme di metodo: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions

cambio Da id a key e attributi, allora probabilmente non sarà necessario utilizzare SingleResult.

  • Se il percorso contiene una chiave, l'azione deve avere un parametro denominato chiave.
  • Se il percorso contiene una chiave in una proprietà di navigazione, l'azione deve avere un parametro denominato relatedKey.
  • Decorare i parametri chiave e relatedKey con il parametro [FromODataUri].
  • Le richieste POST e PUT accettano un parametro del tipo di entità.
  • PATCH richiede un parametro di tipo Delta, dove T è il tipo di entità.

Sarei interessato a vedere se questo cambia il risultato del test.

+0

Non uso ODataController e routing come/odata/Prodotti (1)/Fornitori (1). E ho visto questo articolo – Marusyk