5

我正在尝试模拟我正在使用的第三方接口(EventStore ClientAPI/IEventStoreConnection),特别是这种方法:

Task<StreamEventsSlice> ReadStreamEventsForwardAsync(string stream, long start, int count, bool resolveLinkTos, UserCredentials userCredentials = null);

我遇到的问题是返回类型StreamEventsSlicereadonly字段和internal构造函数,即

public class StreamEventsSlice
{
    public readonly string Stream;
    //other similar fields

    internal StreamEventsSlice(string stream) //missing other fields
    {
        Stream = stream;
    }
}

在我的测试代码中,我使用 模拟事件存储连接Moq,设置ReadStreamEventsForwardAsyncMethod,并尝试设置返回类型,如下所示:

var connection = new Mock<IEventStoreConnection>();
connection.Setup(s => s.ReadStreamEventsForwardAsync(It.IsAny<string>(), It.IsAny<long>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<UserCredentials>())
    .ReturnsAsync(new StreamsEventSlice { props here });

但是我不能设置属性,或者调用构造函数来代替(我实际上只需要设置两个属性)

我尝试制作一个扩展原始类的存根,然后返回它。尽管我可以隐藏只读属性,但在类上出现错误,提示“StreamEventsSlice 没有采用 0 个参数的构造函数”。给它一个构造函数不起作用,因为我不能调用基本 ctor,因为它是内部的。

当我无法实例化返回类型时,如何模拟接口上的方法?

4

1 回答 1

1

@MindSwipe 链接了两个很好的答案,不幸的是我不能使用这个来构造对象,因为构造函数的参数之一也设置为内部。相反,我不得不使用这种方法,并使用他们的其他建议来设置属性。

我保持大部分模拟设置代码相同,然后添加并使用以下方法进行实例化StreamEventsSlice

internal StreamEventsSlice GetStreamEventSlice(ResolvedEvent[] events = null, bool isEndOfStream = true)
{
    events = events ?? new ResolvedEvent[0];
    var type = typeof(StreamEventsSlice);
    var slice = (StreamEventsSlice) FormatterServices.GetUninitializedObject(type);
    type.GetField("Events").SetValue(slice, events);
    type.GetField("IsEndOfStream").SetValue(slice, isEndOfStream);

    return slice;
}
于 2019-08-30T13:14:39.680 回答