public async Task BindModelAsync_MissingOrInvalidComponents_FailsBinding(string day, string month, string year)
        {
            // Arrange
            var modelType = typeof(Date);

            var valueProvider = new SimpleValueProvider();

            if (day != null)
            {
                valueProvider.Add("TheModelName.Day", day);
            }

            if (month != null)
            {
                valueProvider.Add("TheModelName.Month", month);
            }

            if (year != null)
            {
                valueProvider.Add("TheModelName.Year", year);
            }

            ModelBindingContext bindingContext = new DefaultModelBindingContext()
            {
                ActionContext = CreateActionContextWithServices(),
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType),
                ModelName     = "TheModelName",
                ModelState    = new ModelStateDictionary(),
                ValueProvider = valueProvider
            };

            var converterMock = new Mock <DateInputModelConverter>();

            converterMock.Setup(mock => mock.CanConvertModelType(modelType)).Returns(true);

            var modelBinder = new DateInputModelBinder(converterMock.Object);

            // Act
            await modelBinder.BindModelAsync(bindingContext);

            // Assert
            Assert.Equal(ModelBindingResult.Failed(), bindingContext.Result);

            Assert.Equal(day, bindingContext.ModelState["TheModelName.Day"].AttemptedValue);
            Assert.Equal(month, bindingContext.ModelState["TheModelName.Month"].AttemptedValue);
            Assert.Equal(year, bindingContext.ModelState["TheModelName.Year"].AttemptedValue);
        }
        public async Task MissingOrInvalidComponents_FailsBinding(
            string day,
            string month,
            string year,
            string expectedDayModelError,
            string expectedMonthModelError,
            string expectedYearModelError)
        {
            // Arrange
            var modelType = typeof(Date);

            var valueProvider = new SimpleValueProvider();

            if (day != null)
            {
                valueProvider.Add("TheModelName.Day", day);
            }

            if (month != null)
            {
                valueProvider.Add("TheModelName.Month", month);
            }

            if (year != null)
            {
                valueProvider.Add("TheModelName.Year", year);
            }

            ModelBindingContext bindingContext = new DefaultModelBindingContext()
            {
                ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType),
                ModelName     = "TheModelName",
                ModelState    = new ModelStateDictionary(),
                ValueProvider = valueProvider
            };

            var modelBinder = new DateInputModelBinder();

            // Act
            await modelBinder.BindModelAsync(bindingContext);

            // Assert
            Assert.Equal(ModelBindingResult.Failed(), bindingContext.Result);

            var topLevelError = Assert.Single(bindingContext.ModelState["TheModelName"].Errors);

            Assert.Equal("Invalid date specified.", topLevelError.Exception.Message);

            if (expectedDayModelError != null)
            {
                var dayError = Assert.Single(bindingContext.ModelState["TheModelName.Day"].Errors);
                Assert.Equal(expectedDayModelError, dayError.Exception.Message);
            }

            if (expectedMonthModelError != null)
            {
                var monthError = Assert.Single(bindingContext.ModelState["TheModelName.Month"].Errors);
                Assert.Equal(expectedMonthModelError, monthError.Exception.Message);
            }

            if (expectedYearModelError != null)
            {
                var yearError = Assert.Single(bindingContext.ModelState["TheModelName.Year"].Errors);
                Assert.Equal(expectedYearModelError, yearError.Exception.Message);
            }

            Assert.Equal(day, bindingContext.ModelState["TheModelName.Day"].AttemptedValue);
            Assert.Equal(month, bindingContext.ModelState["TheModelName.Month"].AttemptedValue);
            Assert.Equal(year, bindingContext.ModelState["TheModelName.Year"].AttemptedValue);
        }