c# - FakeItEasy 抛出 ExpectationException

标签 c# .net unit-testing mocking fakeiteasy

我在使用(异步)方法模拟接口(interface)时遇到问题。界面如下所示:

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

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

.. 上面的 cancellationToken 参数总是在运行时(通过 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 一个有效/抛出一个期望异常。

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

我有点不确定 FakeItEasy 如何执行签名/参数值匹配,因为理论上调用是模拟的,但 FakeItEasy 说不是。到目前为止它正在获胜..

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

最佳答案

为了对这个问题有一个“答案”,这样新手就不必通过评论和要点以及诸如此类的东西来解决问题,这是我对发生的事情的理解:

在原题中,调用

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

不抛出,但后来当执行生产代码并调用 testDataAccessLayer 时,配置的方法没有执行——FakeItEasy 认为调用不匹配配置的内容。

这是因为在设置调用和实际调用之间,DateOfBirth 最终被 Jil 序列化和反序列化。 ,如图this gist ,并且 DateTime 失去精度,因此参数不再相同。因此,FakeItEasy 认为没有必要拦截调用。

正如 Jörg B. 在评论中提到的,FakeItEasy 没有问题。它正在根据提供的数据尽力而为。

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

相关文章:

c# - 异步 FileStream 读取的正确结构

c# - 如何区分逻辑上命名相同的命令模式中的包装层?

.net - NHibernate 通过 where 选择将一张表映射到两个类

c# - 为什么在 IIS 上的网站下作为应用程序托管时 swagger.json 找不到错误?

java - 使用 Mockito 测试委托(delegate)方法

c# - 传递给函数的参数数量?

.net - 什么时候确定泛型类型?可以影响吗?

unit-testing - 如何在 react 组件的子组件中模拟 e.preventDefault

c++ - 为一个类编写单元测试

C# mvc5 - 检查用户是否在每个 Controller 方法中经过身份验证的简单方法