我们一直在使用最小起订量,它严重依赖于表达式树和反射.emit。但是 Span 不允许出现在表达式树中,因此接受或返回 Span 的方法不能用它来模拟。
我们一直在通过自己实现接口来手动创建模拟来解决这个问题。但这很耗时,而且远非理想。
如何模拟采用或返回 Span 的方法?
我会在这里冒险,因为我专注于使其可测试,也许缺少一些其他考虑因素。我看到的一种选择是引入一个包装器 SpanProvider,它将推迟 Span 的构造,直到您运行用例。
public class SpanTests
{
[Fact]
public void SpanReturningDependencyTest()
{
var spanDependency = new Moq.Mock<IDependencyReturningSpan>();
spanDependency.Setup(g => g.SpanUseCase()).Returns(new SpanProvider<int>(
// test case data
[2, 3, 4]
));
var spanConsumer = new SpanConsumer(spanDependency.Object);
Span<int> result = spanConsumer.GetResultUsingSpan();
result[0].Should().Be(2);
result[1].Should().Be(3);
result[2].Should().Be(4);
}
public interface ISpanProvider<T> where T : struct
{
public Span<T> ToSpan();
}
public class SpanProvider<T> : ISpanProvider<T> where T : struct
{
private readonly T[] values;
public SpanProvider(T[] values) => this.values = values;
public Span<T> ToSpan() => new Span<T>(values);
}
public interface IDependencyReturningSpan
{
SpanProvider<int> SpanUseCase();
}
public class SpanGetter : IDependencyReturningSpan
{
public SpanProvider<int> SpanUseCase() => new SpanProvider<int>(
// use case data
new int[] { 1, 2, 3 }
);
}
public class SpanConsumer
{
private readonly IDependencyReturningSpan spanGetter;
public SpanConsumer(IDependencyReturningSpan spanGetter) => this.spanGetter = spanGetter;
public Span<int> GetResultUsingSpan()
{
Span<int> useCaseSpan = spanGetter.SpanUseCase().ToSpan();
return useCaseSpan;
}
}
}