我有一个单元测试应该返回指定的对象,但它返回了 null。
要测试的数据提供者:
public class PlanDataProvider : BaseDomainServiceProvider, IPlanDataProvider
{
//CTOR
public PlanDataProvider(IDataAccessTemplate template, IEntityStore entityStore) : base(template, entityStore)
{
}
public async Task<DefaultActionPlan> GetDefaultActionPlan(string referenceListId)
{
var objectId = GetObjectId(referenceListId);
var defaultActionPlan = await Template.InvokeAsync(context => Task.FromResult(EntityStore.GetEntityById<DefaultActionPlan, ObjectId>
(
context.ActivityContext as IDataAccessContext,
typeof(DefaultActionPlan).FullName,
objectId
)));
}
}
测试:
public async Task GetPlan_BadPlanID()
{
//Arrange
string badPlanId = "57509afbc6b48d3f33b2dfcd";
...snip...
DefaultActionPlan jj = new ObjectId(badPlanId);
//create EntityStore object
var dataxs = Substitute.For<IDataAccessContext>();
var estore = Substitute.For<IEntityStore>();
estore.GetEntityById<DefaultActionPlan, ObjectId>(
dataxs,
typeof(DefaultActionPlan).FullName,
new ObjectId(badPlanId))
.Returns(Task.FromResult(jj).Result);
var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();
PlanDataProvider pdp = new PlanDataProvider(dataAccessTemplate, estore);
//Act
var t = await pdp.GetDefaultActionPlan(badPlanId);
//Now this confuses me as the compiler thinks t is DefaultActionPlan NOT Task<DefaultActionPlan>???
}
无论如何 t 返回 null eferytime 并调试测试 t 为 null 因为 GetDefaultActionPlan 没有返回 jj 而是返回 null??
让 jj 返回我缺少什么?
编辑:
Eris 和 Gabe 都正确地指出,我对 IEntityStore 的模拟不足以作为该值...即使它指定返回不会传递给包装 InvokeAsync,因此我也需要模拟 InvokeAsync。
Gabe 的回答略有偏差,因为通过 Arg.Any 不满足 InvokeAsync 所需的参数。但是我并没有因此而责怪他,因为我花了一个小时跟踪跨多个项目的继承链(这是一家大公司)。他无权做的事情。
最后是导致成功的代码:
var estore = Substitute.For<IEntityStore>();
var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();
dataAccessTemplate.InvokeAsync(context => Task.FromResult(
estore.GetEntityById<DefaultActionPlan>(
dataxs, typeof(DefaultActionPlan).FullName, new ObjectId(badPlanId))))
.ReturnsForAnyArgs(jj);
var pdp = new PlanDataProvider(dataAccessTemplate, estore);
最佳答案
虽然我在您的代码中没有看到这一点,但我会假设 GetDefaultActionPlan 返回 defaultActionPlan 变量,并且 Template.InvokeAsync 指的是通过构造函数传入的 IDataAccessTemplate。
看起来您缺少 Template.InvokeAsync 的模拟返回值,并且由于它包装了另一个调用,因此您只关心它的返回值:
var estore = Substitute.For<IEntityStore>();
var dataAccessTemplate = Substitute.For<IDataAccessTemplate>();
dataAccessTemplate.InvokeAsync(context => Task.FromResult(Arg.Any<DefaultActionPlan>)
.ReturnsForAnyArgs(jj);
var pdp = new PlanDataProvider(dataAccessTemplate, estore);
关于c# - 尽管定义了返回对象,NSubstitute Async 仍返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37837826/