You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There may be more than one Add method which then causes an exception from SingleOrDefault
It finds any method called Add. It should likely specifically select ICollection<>.Add (though that's probably still not fully specific as the type may implement multiple ICollection<>)
Scenario
In this scenario the readonly collection property is a Dictionary<,> which has multiple Add methods.
using System.Collections.Generic;using System.Linq;using AutoFixture;using Xunit;publicclassBugs{classMultipleAddMethodsModel{publicDictionary<int,int> Items {get;}=new();}[Fact]publicvoidMultipleAddMethods(){varfixture=new Fixture();
fixture.Behaviors.Add(new ReadonlyCollectionPropertiesBehavior());// Throws
fixture.Create<MultipleAddMethodsModel>();}}/*System.InvalidOperationExceptionSequence contains more than one element at System.Linq.ThrowHelper.ThrowMoreThanOneElementException() at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Boolean& found) at AutoFixture.Kernel.ReadonlyCollectionPropertiesCommand.Execute(Object specimen, ISpecimenContext context) at AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at AutoFixture.Fixture.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.SpecimenContext.Resolve(Object request) at AutoFixture.Kernel.SeedIgnoringRelay.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context) at AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)*/
Expected Behavior
Code above should not throw. Items should be added to the dictionary.
Tasks
Using AutoFixture 4.17
The text was updated successfully, but these errors were encountered:
The current source code expects the following:
The ReadOnlyCollection implements ICollection and has public Add(T item) method.
As you are using a Dictionary<TKey, TValue> that is not the case. As this class implements ICollection<KeyValuePair<TKey, TValue>> and explicitly implements the interface.
Simplified AutoFixture uses the following code:
MethodInfo GetAddMethod(object obj)
{
var type = obj.GetType();
return type.GetMethod(nameof(ICollection<object>.Add));
}
while it should use this
static MethodInfo GetAddMethod(object obj)
{
var type = obj.GetType();
var collectionType = type.GetInterfaces()
.Where(i => i.IsGenericType)
.Single(i => i.GetGenericTypeDefinition() == typeof(ICollection<>));
return collectionType.GetMethod(nameof(ICollection<object>.Add));
}
Describe the Bug
ReadonlyCollectionPropertiesBehavior
does not select collectionAdd
method correctly.The
ReadonlyCollectionPropertiesCommand
class tries to select any method calledAdd
:AutoFixture/Src/AutoFixture/Kernel/ReadonlyCollectionPropertiesCommand.cs
Lines 57 to 62 in 730b478
This is incorrect in two ways:
Add
method which then causes an exception fromSingleOrDefault
Add
. It should likely specifically selectICollection<>.Add
(though that's probably still not fully specific as the type may implement multipleICollection<>
)Scenario
In this scenario the readonly collection property is a
Dictionary<,>
which has multipleAdd
methods.Expected Behavior
Code above should not throw. Items should be added to the dictionary.
Tasks
Using AutoFixture 4.17
The text was updated successfully, but these errors were encountered: