我有一个单元测试,应该返回指定的对象,但它返回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,调试测试时t为空,因为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);
IDataAccessTemplate
创建替代品时,您从未定义其任何方法。await Template.InvokeAsync
是调用InvokeAsync
的空模拟还是实际调用带有参数的方法? - Eris