Как написать модульный тест для пользовательского связывателя модели в ядре ASP.net

Я написал настраиваемую привязку модели для свойства. Теперь я пытаюсь написать модульный тест для того же самого, но не могу создать объект для связывателя модели. Может кто-нибудь помочь мне ? Ниже приведен код, для которого я должен написать test.

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

person megha    schedule 24.12.2018    source источник


Ответы (2)


Я создал модульный тест с помощью 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);
    }
} 
person Hasan    schedule 24.12.2018

Вы можете использовать экземпляр 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.

person Ray    schedule 27.03.2019
comment
Это почти работает, однако bindingContext.ModelMetaData имеет значение null вместе со всеми другими значениями, которые нужны связывателю модели. - person iGanja; 26.03.2021