У меня есть единичный тест, который должен вернуть указанный объект, но он возвращает null.NSubstitute Async возвращает 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>???
}
Во всяком случае т возвращает нулевое eferytime и отладки тест т равна нулю, так как в GetDefaultActionPlan не возвращающей JJ, но вместо того, чтобы нуль? ?
Что мне не хватает, чтобы вернуть jj?
Edit:
Оба Eris и Гейб справедливо указал, что мой Мок из 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