Насмешка над абстрактным классом с помощью виртуально устанавливаемого свойства в Foq - PullRequest
0 голосов
/ 13 марта 2019

Я написал долговременную функцию Azure на F # и пытаюсь написать модульные тесты, следуя указаниям на https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-unit-testing. Я пытался использовать Foq для создания фиктивного экземпляра абстрактного класса DurableOrchestrationContextBase, нокоторая завершается с ошибкой:

System.TypeLoadException: метод 'set_InstanceId' для типа 'Mock.DurableOrchestrationContextBase1953fcc2-be15-41fc-850c-5a5813aace89' из сборки 'Foq.Dynamic, Version = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null 'переопределяет метод, который не виден из этой сборки.

Ошибка относится к этому свойству:

public virtual string InstanceId { get; internal set; }

Дальнейшее исследование показываетчто Foq может смоделировать не виртуальные, неабстрактные свойства с помощью внутренних сеттеров в абстрактных классах C #, но не может справиться с такими свойствами, если они виртуальные.

Есть ли способ издеваться над таким классомв тесте F #?В этом случае было бы неудобно развертывать мою собственную реализацию, поскольку DurableOrchestrationContextBase - это большой класс, в котором много членов, которые должны быть реализованы.

1 Ответ

0 голосов
/ 18 марта 2019

В конце концов я обошел эту проблему, переключившись на NSubstitute, которая способна издеваться над такого рода классами. API-интерфейс NSubstitute относительно прост в использовании из F #, поскольку (в отличие от Moq, например) вы можете настроить большинство сценариев, не прибегая к деревьям выражений, особенно если вы можете использовать структурное равенство для проверки аргументов. Например:

let returns<'T> (value: 'T) x = x.Returns(value) |> ignore

[<Fact>]
let ``should call my activity``() =
    task {
        // Arrange
        let context = Substitute.For<DurableOrchestrationContextBase>()
        context.GetInput<SomeType>() |> returns { Foo = 42 }

        // Act
        do! runOrchestrator context

        // Assert
        // In C# you would have to do Arg.Is<SomeClass>(x => x.Bar == 43 && x.Baz == "bla")
        do! context.Received().CallActivityAsync("MyActivity", { Bar = 43; Baz = "bla" })
    }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...