首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在单元测试中使用自定义ModelMetadataProvider

在单元测试中使用自定义ModelMetadataProvider
EN

Stack Overflow用户
提问于 2012-11-02 17:39:17
回答 1查看 1.2K关注 0票数 1

这是MVC的新手,所以希望这是一个简单的问题。

我已经编写了一个需要访问httpContext的自定义绑定属性。为了在单元测试期间注入模拟httpContext,我编写了一个InjectingMetadataProvider来填充我的任何自定义属性上的Context属性。

在下面的测试中,我成功地实现了这一点:

代码语言:javascript
复制
[TestMethod]
public void Marker_ShouldBind_Id()
{
    // Arrange
    var formCollection = new NameValueCollection 
    { 
        { "id", "2" }
    };

    var context = new Mock<HttpContextBase>();
    context.Setup(c => c.User).Returns((IPrincipal)null); 

    var metaProvider = new InjectingMetadataProvider(context.Object);
    ModelMetadataProviders.Current = metaProvider;  //why do I need this?

    var bindingContext = new ModelBindingContext
    {
        ModelName     = string.Empty,
        ValueProvider = new NameValueCollectionValueProvider(formCollection, null),
        ModelMetadata = metaProvider.GetMetadataForType(null, typeof(Marker)),
    };

    var binder = new DefaultModelBinder();

    // Act
    var marker = (Marker)binder.BindModel(new ControllerContext(), bindingContext);

    // Assert
    marker.Id.Should().Be(2);
}

但是,如果我注释掉将我的InjectingMetadataProvider设置为ModelMetadataProviders.Current的行,那么我的InjectingMetadataProvider.CreateMetadata()覆盖将得到一个空白的属性列表,因此测试失败,因为我的自定义属性没有获得它们的上下文设置。

当我显式地使用它时,为什么我需要将它设置为Current?我不想在测试中设置静态的东西。

我可能在做一些愚蠢的事情,因为我对框架不熟悉,所以我现在感到有点蒙在鼓里。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-02 23:01:14

在DefaultModelBinder内部,在调用BindComplexElementalModel时会创建一个新的绑定上下文。请注意,它从ModelMetadataProviders.Current而不是您的自定义模型元数据提供程序获取元数据。

代码语言:javascript
复制
  internal ModelBindingContext CreateComplexElementalModelBindingContext(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) {
        BindAttribute bindAttr = (BindAttribute)GetTypeDescriptor(controllerContext, bindingContext).GetAttributes()[typeof(BindAttribute)];
        Predicate<string> newPropertyFilter = (bindAttr != null)
            ? propertyName => bindAttr.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName)
            : bindingContext.PropertyFilter;

        ModelBindingContext newBindingContext = new ModelBindingContext() {
            ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, bindingContext.ModelType),
            ModelName = bindingContext.ModelName,
            ModelState = bindingContext.ModelState,
            PropertyFilter = newPropertyFilter,
            ValueProvider = bindingContext.ValueProvider
        };

        return newBindingContext;
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13192697

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档