2009-07-03 20 views
13

Sto riscontrando qualche difficoltà nella scrittura di alcuni test unitari per testare un ModelBinder personalizzato che ho creato. Il ModelBinder che sto provando per Unit Test è il JsonDictionaryModelBinder che ho postato here.Come testare un ModelBinder personalizzato usando Moq?

Il problema che sto riscontrando è ottenere il Mocking di tutte le impostazioni usando Moq. Continuo a ottenere Eccezioni Null a causa del fatto che HttpContextBase non sia Mocked correttamente. Credo.

Qualcuno potrebbe aiutarmi a capire cosa non sto facendo in modo corretto?

Ecco un esempio di test di unità che sto cercando di scrivere che non funziona:

[TestMethod()] 
public void BindModelTest() 
{ 
    JsonDictionaryModelBinder target = new JsonDictionaryModelBinder(); 

    NameValueCollection nameValueCollection = new NameValueCollection() { 
     {"First", "1"}, 
     {"Second", "2"}, 
     {"Name", "Chris"}, 
     {"jsonValues", "{id: 200, name: 'Chris'}"} 
    }; 

    HttpContextBase httpContext = MockHelper.FakeHttpContext(HttpVerbs.Post, nameValueCollection); 

    ControllerContext controllerContext = 
     new ControllerContext(new RequestContext(httpContext, new RouteData()), new Mock<Controller>().Object); 


    Predicate<string> predicate = propertyName => (propertyName == "jsonValues"); 
    ModelBindingContext bindingContext = new ModelBindingContext() 
    { 
     Model = null, 
     ModelType = typeof(JsonDictionary), 
     ModelState = new ModelStateDictionary(), 
     PropertyFilter = predicate, 
     ValueProvider = new Dictionary<string, ValueProviderResult>() { { "foo", null } } 
    }; 

    //object expected = null; // TODO: Initialize to an appropriate value 
    var actual = target.BindModel(controllerContext, bindingContext) as JsonDictionary; 

    Assert.IsNotNull(actual); 

    Assert.AreEqual("Chris", actual["name"]); 
    //Assert.AreEqual(expected, actual); 
    Assert.Inconclusive("Verify the correctness of this test method."); 
} 

Ecco il metodo "FakeHttpContext" usata in precedenza:

public static class MockHelper 
{ 
    public static HttpContextBase FakeHttpContext(HttpVerbs verbs, NameValueCollection nameValueCollection) 
    { 
     var httpContext = new Mock<HttpContextBase>(); 

     var request = new Mock<HttpRequestBase>(); 
     request.Setup(c => c.Form).Returns(nameValueCollection); 
     request.Setup(c => c.QueryString).Returns(nameValueCollection); 

     var response = new Mock<HttpResponseBase>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     var server = new Mock<HttpServerUtilityBase>(); 
     httpContext.Setup(c => c.Request).Returns(request.Object); 

     var u = verbs.ToString().ToUpper(); 
     httpContext.Setup(c => c.Request.RequestType).Returns(
      verbs.ToString().ToUpper() 
     ); 

     httpContext.Setup(c => c.Response).Returns(response.Object); 
     httpContext.Setup(c => c.Server).Returns(server.Object); 
     httpContext.Setup(c => c.User.Identity.Name).Returns("testclient"); 
     return httpContext.Object; 
    } 
} 

risposta

7

Il colpevole è questo line:

httpContext.Setup(c => c.Request.RequestType).Returns(
       verbs.ToString().ToUpper() 
      ); 

Questo è tecnicamente una seconda Setup sull'oggetto Request, un d sta cancellando l'originale Setup, anche se lo stai "incollando" nella gerarchia degli oggetti. Non sono sicuro che si tratti di un bug in Moq o di un comportamento desiderato, anche in questo caso mi sono imbattuto in questo e non sono riuscito a controllarlo.

Puoi risolverlo spostando quella linea nel punto in cui stai configurando la tua richiesta di sopra, e impostandola direttamente, piuttosto che passando attraverso httpContext. Così,

request.Setup(c => c.RequestType).Returns(verbs.ToString().ToUpper()); 

Ho anche notato che il "var u" che si dichiara non viene utilizzato;)

+0

impressionante, grazie! –

Problemi correlati