【问题标题】:How to write unit test for custom model binder in ASP.net core如何在 ASP.net 核心中为自定义模型绑定器编写单元测试
【发布时间】:2019-05-23 09:24:50
【问题描述】:

我已经为一个属性编写了自定义模型绑定器。现在我正在尝试为相同的单元测试编写单元测试,但无法为模型绑定器创建对象。谁能帮我 ?下面是我必须编写测试的代码。

public class JourneyTypesModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        bool IsSingleWay = Convert.ToBoolean((bindingContext.ValueProvider.GetValue("IsSingleWay")).FirstValue);
        bool IsMultiWay = Convert.ToBoolean((bindingContext.ValueProvider.GetValue("IsMultiWay")).FirstValue);

        JourneyTypes journeyType = JourneyTypes.None;
        bool hasJourneyType = Enum.TryParse((bindingContext.ValueProvider.GetValue("JourneyType")).FirstValue, out journeyType);
        if (!hasJourneyType)
        {
            if (IsSingleWay)
                journeyType = JourneyTypes.Single;
            else journeyType = JourneyTypes.MultiWay;
        }

        bindingContext.Result = ModelBindingResult.Success(journeyType);
        return Task.CompletedTask;
    } }  

【问题讨论】:

    标签: c# unit-testing asp.net-core xunit custom-model-binder


    【解决方案1】:

    我使用 Nunit 创建了单元测试(这与 XUnit 几乎相同),并使用 Moq 模拟了依赖项。由于在线 C# 编译器可能会出现一些错误,但下面显示的代码将为您提供思路。

    [TestFixture]
    public class BindModelAsyncTest()
    {
        private JourneyTypesModelBinder _modelBinder;
        private Mock<ModelBindingContext> _mockedContext;
    
        // Setting up things
        public BindModelAsyncTest()
        {
            _modelBinder = new JourneyTypesModelBinder();
            _mockedContext = new Mock<ModelBindingContext>();
    
            _mockedContext.Setup(c => c.ValueProvider)
                .Returns(new ValueProvider() 
                {
                    // Initialize values that are used in this function
                    // "IsSingleWay" and the other values
                });
        }
    
        private JourneyTypesModelBinder CreateService => new JourneyTypesModelBinder();
    
        [Test]                       
        public Task BindModelAsync_Unittest()
        {
            //Arrange
            //We set variables in setup function.
            var unitUnderTest = CreateService();
    
            //Act
            var result = unitUnderTest.BindModelAsync(_mockedContext);
    
            //Assert
            Assert.IsNotNull(result);
            Assert.IsTrue(result is Task.CompletedTask);
        }
    } 
    

    【讨论】:

      【解决方案2】:

      您可以使用实例DefaultModelBindingContext 传入BindModelAsync()

          [Fact]
          public void JourneyTypesModelBinderTest()
          {
              var bindingContext = new DefaultModelBindingContext();
      
              var bindingSource = new BindingSource("", "", false, false);
              var routeValueDictionary = new RouteValueDictionary
              {
                  {"IsSingleWay", true},
                  {"JourneyType", "Single"}
              };
              bindingContext.ValueProvider = new RouteValueProvider(bindingSource, routeValueDictionary);
      
              var binder = new JourneyTypesModelBinder();
              binder.BindModelAsync(bindingContext);
      
              Assert.True(bindingContext.Result.IsModelSet);
              Assert.Equal(JourneyTypes.Single, bindingContext.Result.Model);
          }
      

      这可以替代为bindingContext 使用模拟对象。

      【讨论】:

      • 这几乎可以工作,但是 bindingContext.ModelMetaData 以及模型绑定器需要的所有其他值都是空的。
      猜你喜欢
      • 2019-11-14
      • 1970-01-01
      • 2022-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-09
      • 2017-03-03
      • 1970-01-01
      相关资源
      最近更新 更多