asp.net mvc和linq to entities:如何测试模型自定义绑定?

时间:2022-11-30 16:22:49

I'm trying to build a test for my custom model binder, but not having any success. The call to base.BindModel always returns a null. Is there a way to test custom binding when using LINQ to Entities? foo in this case is a table in the db with two fields - a numeric and a text value.

我正在尝试为我的自定义模型绑定器构建测试,但没有取得任何成功。对base.BindModel的调用始终返回null。有没有办法在使用LINQ to Entities时测试自定义绑定?在这种情况下,foo是db中的一个表,有两个字段 - 数字和文本值。

fooBinder.cs:

public override Object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
  var obj = (foo)base.BindModel(controllerContext, bindingContext);
  return obj;
}

I'm trying to do a simple test (there's some extra debris in here, I've tried a number of different approaches):

我正在尝试做一个简单的测试(这里有一些额外的碎片,我尝试了很多不同的方法):

fooBinderTest.cs:

fooBinder binder;
ControllerContext controllerContext;
ModelBindingContext bindingContext;

[TestInitialize]
public void Initialize()
{
  controllerContext = MockControllerContext().Object;

  FormCollection form = new FormCollection
      {
        {"foo_A","2" },
        {"foo_B", "FooB" }
      };
  var valueProvider = form.ToValueProvider();

  bindingContext = new ModelBindingContext()
  {
    ModelState = new ModelStateDictionary(),
    ModelType = typeof(foo),
    ModelName = "foo",
    ValueProvider = valueProvider
  };

  binder = new fooBinder();

}

public static Mock<ControllerContext> MockControllerContext()
{
  var context = new Mock<ControllerContext>();
  var sessionState = new Mock<HttpSessionStateBase>();
  var response = new Mock<HttpResponseBase>();
  var request = new Mock<HttpRequestBase>();
  var serverUtility = new Mock<HttpServerUtilityBase>();

  var form = new FormCollection
        {
        {"foo_A","2" },
        {"foo_B", "FooB" }
        };

  context.Setup(c => c.HttpContext.Session).Returns(sessionState.Object);
  context.Setup(c => c.HttpContext.Response).Returns(response.Object);
  context.Setup(c => c.HttpContext.Request).Returns(request.Object);
  context.Setup(c => c.HttpContext.Server).Returns(serverUtility.Object);
  context.Setup(c => c.HttpContext.User.Identity.Name).Returns("Test");
  context.Setup(c => c.HttpContext.Request.Form).Returns(form);

  return context;
}


[TestMethod]
public void TestDefault()
{
  foo myFoo = (foo)binder.BindModel(controllerContext, bindingContext);
  Assert.IsNotNull(myFoo);
}

1 个解决方案

#1


1  

L2E is a red herring here.

L2E在这里是一个红鲱鱼。

You must specify your custom model binder since you don't have the MVC infrastructure running in the test.

您必须指定自定义模型绑定器,因为您没有在测试中运行MVC基础结构。

Here's how I do it (MVC 2; 1 is a bit different).

这是我的方式(MVC 2; 1有点不同)。

    internal static T Bind<T>(string prefix, FormCollection collection, ModelStateDictionary modelState)
    {
        var mbc = new ModelBindingContext()
        {
            ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(T)),
            ModelName = prefix,
            ModelState = modelState,
            ValueProvider = collection.ToValueProvider()
        };
        IModelBinder binder = new MyCustomModelModelBinder();
        var cc = new ControllerContext();

        return binder.BindModel(cc, mbc) as T;
    }

    internal static T BindAndAssertValid<T>(string prefix, FormCollection collection)
    {
        var msd = new ModelStateDictionary();
        var result = Bind<T>(prefix, collection, msd);
        if (!msd.IsValid)
        {
            Assert.Fail(ModelStateValidationSummary(msd));
        }
        return result;
    }

#1


1  

L2E is a red herring here.

L2E在这里是一个红鲱鱼。

You must specify your custom model binder since you don't have the MVC infrastructure running in the test.

您必须指定自定义模型绑定器,因为您没有在测试中运行MVC基础结构。

Here's how I do it (MVC 2; 1 is a bit different).

这是我的方式(MVC 2; 1有点不同)。

    internal static T Bind<T>(string prefix, FormCollection collection, ModelStateDictionary modelState)
    {
        var mbc = new ModelBindingContext()
        {
            ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(T)),
            ModelName = prefix,
            ModelState = modelState,
            ValueProvider = collection.ToValueProvider()
        };
        IModelBinder binder = new MyCustomModelModelBinder();
        var cc = new ControllerContext();

        return binder.BindModel(cc, mbc) as T;
    }

    internal static T BindAndAssertValid<T>(string prefix, FormCollection collection)
    {
        var msd = new ModelStateDictionary();
        var result = Bind<T>(prefix, collection, msd);
        if (!msd.IsValid)
        {
            Assert.Fail(ModelStateValidationSummary(msd));
        }
        return result;
    }