我在用(异步)方法模拟接口时遇到了问题。接口如下所示:
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 1做而不是工作/抛出ExpectationException。
我已经检查了正在测试的底层代码,并且正在使用.CreateUserAsync(.)的相同值进行调用。方法被使用了&我怀疑dateOfBirth是罪魁祸首,但至少.Ticks智慧是完全相同的。
对于FakeItEasy是如何执行签名/参数值匹配的,我有点不确定,因为理论上这个调用是模拟的,但是FakeItEasy说没有。到目前为止它正在获胜..。
有人知道我在上面模仿调用的方法有什么问题吗?
发布于 2014-10-14 15:20:10
为了对这个问题有一个“答案”,新来的人不必经过评论、专家和诸如此类的东西才能弄清楚,下面是我对所发生的事情的理解:
在最初的问题中,
A.CallTo(() => testDataAccessLayer.CreateUserAsync(
validSignupRequest.Username,
validSignupRequest.Password,
validSignupRequest.DateOfBirth,
CancellationToken.None))
.Returns(fakeUserInstance); 不会抛出,但稍后当执行生产代码并调用testDataAccessLayer时,未执行已配置的方法--FakeItEasy不认为调用与配置的匹配。
这是因为在设置调用和实际调用之间,DateOfBirth最终被吉尔序列化和反序列化,如这个要旨所示,而DateTime失去了精度,因此参数不再相同。因此,FakeItEasy认为没有必要拦截呼叫。
正如J rg.在评论中提到的,FakeItEasy没有问题。它正在尽最大努力处理所提供的数据。
发布于 2014-10-12 19:28:39
这只是猜测,因为我不熟悉FakeItEasy,但也许您需要等待异步调用的结果。
A.CallTo(async () => await testDataAccessLayer.CreateUserAsync( // await the result
validSignupRequest.Username, validSignupRequest.Password, validSignupRequest.DateOfBirth, CancellationToken.None))
.Returns(fakeUserInstance);或者,根据FakeItEasy内部的工作方式,可能取决于您检查结果的方式:
A.CallTo(() => testDataAccessLayer.CreateUserAsync(
validSignupRequest.Username, validSignupRequest.Password, validSignupRequest.DateOfBirth, CancellationToken.None))
.Returns(Task.FromResult(fakeUserInstance)); // test a task, not a real object快速搜索发现了此页,它倾向于第二种解决方案,但我认为两者都可能有效。
https://stackoverflow.com/questions/26329057
复制相似问题