我在模拟带有(异步)方法的接口时遇到问题。接口看起来像这样:

public interface IDataAccessLayer
    {
        Task<bool> ExistsUserAsync(string username, CancellationToken cancellationToken);

        Task<IUser> CreateUserAsync(string username, string password, DateTime dateOfBirth, CancellationToken cancellationToken);
    }


..在那里的cancelestToken参数总是在运行时(通过NancyFx)以及在像这样的测试方法中模拟调用时从外部创建和传递的:

    var validSignupRequest = new UserSignupRequest()
    {
        Username = "meh-spacey_space",
        DateOfBirth = DateTime.Now.Subtract(TimeSpan.FromDays(365*35)),
        Password = "someproper_passw*rd"
    };

    var testDataAccessLayer = A.Fake<IDataAccessLayer>(options => options.Strict());

    var fakeUserInstance = A.Fake<IUser>();

    A.CallTo(() => fakeUserInstance.Username).Returns(validSignupRequest.Username);
    A.CallTo(() => testDataAccessLayer.ExistsUserAsync(validSignupRequest.Username, CancellationToken.None)).Returns(false); // works
    A.CallTo(() => testDataAccessLayer.CreateUserAsync(validSignupRequest.Username, validSignupRequest.Password, validSignupRequest.DateOfBirth, CancellationToken.None)).Returns(fakeUserInstance); // does not work / throws ExpectationException


..对.ExistsUserAsync(...)的模拟调用确实起作用,.CreateUserAsync一个不起作用/抛出了ExpectationException。

我已经检查了正在测试的基础代码,并且使用与.CreateUserAsync(...)方法相同的值进行调用,并且我怀疑dateOfBirth是罪魁祸首,但至少.Ticks明智地是一模一样。

对于FakeItEasy如何执行签名/参数值匹配,我有点不确定,因为从理论上讲,调用IS是模拟的,但是FakeItEasy说不是。到目前为止,它是赢家。

有人知道我的方法模拟调用出了什么问题吗?

最佳答案

为了对这个问题有一个“答案”,这样新来的人就不必遍历评论和要旨,而不必弄清楚事情了,这是我对所发生事情的理解:

在原始问题中,电话

A.CallTo(() => testDataAccessLayer.CreateUserAsync(
                         validSignupRequest.Username,
                         validSignupRequest.Password,
                         validSignupRequest.DateOfBirth,
                         CancellationToken.None))
               .Returns(fakeUserInstance);


不会抛出,但是稍后在执行生产代码并调用testDataAccessLayer时,未执行配置的方法-FakeItEasy不认为该调用与配置的匹配。

这是因为在设置呼叫和实际呼叫之间,DateOfBirth最终被Jil序列化和反序列化,如this gist所示,并且DateTime失去了精度,因此参数不再相同。因此,FakeItEasy认为不需要拦截该呼叫。

正如JörgB.在评论中提到的那样,FakeItEasy没有问题。它使用给出的数据正在尽力而为。

关于c# - FakeItEasy引发ExpectationException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26329057/

10-11 02:24