2009-07-03 2 views
13

У меня возникли трудности с написанием некоторых тестов модулей для тестирования пользовательского ModelBinder, который я создал. ModelBinder Я пытаюсь выполнить Unit Test - это JsonDictionaryModelBinder, который я опубликовал here.Как выполнить тестирование пользовательского ModelBinder с помощью Moq?

Проблема, с которой я столкнулась, заключается в том, чтобы получить Mocking all setup с помощью Moq. Я продолжаю получать Null Exceptions из-за того, что HttpContextBase не исправляется правильно. Я думаю.

Не мог бы кто-нибудь помочь мне разобраться, что я не делаю с корреляцией?

Вот образец испытуемой единицы я пытаюсь написать, что не работает:

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

Вот метод «FakeHttpContext», использованный выше:

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

ответ

7

Виновником это линия:

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

Это технически второй Setup на объект запроса, А.Н. d он уничтожает оригинал Setup, даже если вы собираетесь «пройти» его в иерархии объектов. Я не уверен, что это ошибка в Moq или желаемое поведение, и я столкнулся с этим раньше, и не стал проверять его.

Вы можете решить эту проблему, переместив эту строку туда, где вы настраиваете свой запрос выше, и настраиваете его напрямую, а не через httpContext. Так,

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

Я также заметил, что «вар и» что вы объявляете не используется;)

+0

Удивительного спасибо! –

Смежные вопросы