我用F#编写了一个Azure持久函数,并试图按照https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-unit-testing的指导原则编写单元测试。我尝试使用Foq创建抽象类DurableOrchestrationContextBase的模拟实例,但失败了,出现了以下错误:
'Mock.DurableOrchestrationContextBase1953fcc2-be15-41fc-850c-5a5813aace89‘类型的System.TypeLoadException :来自程序集'Foq.Dynamic,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null’的方法'set_InstanceId‘正在覆盖该程序集中不可见的方法。
此错误与此属性有关:
public virtual string InstanceId { get; internal set; }进一步研究表明,Foq能够在抽象C#类上使用内部设置器模拟非虚拟、非抽象属性,但如果这些属性是虚拟的,则无法处理这些属性。
在F#测试中有任何方法来模拟这样的类吗?在这种情况下,滚动我自己的实现会很尴尬,因为DurableOrchestrationContextBase是一个很大的类,有许多需要实现的成员。
发布于 2019-03-18 17:37:05
最后,我通过切换到NSubstitute来解决这个问题,它能够模拟这类类。NSub妓女的API相对容易从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" })
}https://stackoverflow.com/questions/55143187
复制相似问题