Reputation: 31
I have an entity aggregate (WeeklyMenuItem) containing a sub-entity (WeeklyMenuItemIngredient) as a collection. The WeeklyMenuItemIngredient can only be set via methods (AddOrUpdateIngredient, RemoveIngredient). The public collection is a IReadOnlyCollection with a private readonly List.
I want to create a test for "adding ingredients" using NSubstitute. The AddOrUpdateIngredient method of the substitute adds the ingredient to the private list, but later I cannot access the value through the public ReadOnlyCollection.
If I create the WeeklyMenuItem as a normal class, I can access the value. Only the substitute has the problem.
Does NSubstitute not support IReadOnlyCollections?
The WeeklyMenuItem with ReadOnlyCollection and AddOrUpdateIngredient method:
public partial class WeeklyMenuItem(long dayId,
long? createdById = null,
long? createdId = null,
long? updatedById = null,
long? updatedId = null) : BaseEntity<long>, IAggregateRoot
private readonly List<WeeklyMenuItemIngredient> _weeklyMenuItemIngredient = [];
public virtual IReadOnlyCollection<WeeklyMenuItemIngredient> WeeklyMenuItemIngredient => _weeklyMenuItemIngredient.AsReadOnly();
public void AddOrUpdateIngredient(long ingredientId, decimal amount)
{
if (!WeeklyMenuItemIngredient.Any(e => e.WeeklyMenuItemId == this.Id && e.IngredientId == ingredientId))
{
_weeklyMenuItemIngredient.Add(new WeeklyMenuItemIngredient(this.Id, ingredientId, amount));
return;
}
var dishIngredient = WeeklyMenuItemIngredient.First(e => e.WeeklyMenuItemId == this.Id && e.IngredientId == ingredientId);
dishIngredient.SetAmount(amount);
}
The XUnit test with the substitute creation methods:
private readonly decimal amount1 = 1;
private readonly decimal amount2 = 2;
[Fact]
public void AddIngredient()
{
var weeklyMenuItem1 = new WeeklyMenuItem(1, null, null, null, null); //working
var weeklyMenuItem1 = WeeklyMenuItemTestData.GetWeeklyMenuItem1(DayTestData.GetDay1(WeekTestData.GetWeek1())); //not working
var ingredient1 = IngredientTestData.GetIngredient1();
weeklyMenuItem1.AddOrUpdateIngredient(ingredient1.Id, amount1);
var addedIngredient1 = weeklyMenuItem1.WeeklyMenuItemIngredient.FirstOrDefault(); //Empty - result is null value
weeklyMenuItem1.WeeklyMenuItemIngredient.Should().HaveCount(1);
addedIngredient1.Should().NotBeNull();
addedIngredient1!.IngredientId.Should().Be(ingredient1.Id);
addedIngredient1!.Amount.Should().Be(amount1);
}
public static WeeklyMenuItem GetWeeklyMenuItem1(Day? day)
{
var weeklyMenuItem1 = Substitute.For<WeeklyMenuItem>(day?.Id, null, null, null, null);
weeklyMenuItem1.Id.Returns(Id1);
weeklyMenuItem1.Day.Returns(day);
return weeklyMenuItem1;
}
public static Day GetDay1(Week? week)
{
var day1 = Substitute.For<Day>(Date1, week?.Id, BusinessesIsOpen);
day1.Id.Returns(Id1);
day1.Week.Returns(week);
return day1;
}
public static Week GetWeek1()
{
var week1 = Substitute.For<Week>(Year1, Value1);
week1.Id.Returns(Id1);
return week1;
}
Upvotes: 0
Views: 19