My test requires that I have different counts of objects in an IEnumerable property of the main entity collection. I have been searching for documentation about this but can't find anything. Here is a sample of what I mean (note that the base entity is created using AutoNSubstituteCustomization
)
IFixture fixture = new Fixture().Customize(new AutoNSubstituteCustomization() { ConfigureMembers = true });
var t = fixture.CreateMany<ITransaction>(5)
var service1 = Substitute.For<ITransactionsSvc>();
service1.GetTransactions().ReturnsForAnyArgs(t);
var service2 = Substitute.For<IRequestsSvc>();
service2.GetRequest(default).ReturnsForAnyArgs(
new Result(){
TransactionId = t.First().Files.First().RequestId
}
);
Where ITransaction
would look like
public interface ITransaction
{
long RequestId { get; }
IEnumerable<FileDef> Files { get; }
IEnumerable<Comment> Comments { get; }
}
I know I could set fixture.RepeatCount
to specify the global count but how can I have a different value for Files and Comments?
I already tried using t.With(x => x.Files, () => fixture.CreateMany<FileDef>(rnd.Next(1,5))
but it throws saying this is a readonly property.
I also tried using NSubstitute .Returns
on the t.Files
property but for some reason, the type of RequestId
got changed from Int64 to Task`1 when trying to read the value for service2 ReturnForAnyArgs
response.
I know I had to remove some of the complexity from the real case so that is stays concise so I hope I didn't remove too much and kept it understandable. If you need any precisions, feel welcome to ask.
Sub-question: is there any complete documentation on AutoFixture? On AutoFixture website I was only able to find very introductory documentation.
In fact, as @AndreiIvascu mentionned, the problem AND the cleanest solution I found were linked to NSubstitute. Since NSubstitute is creating the instances, theses instances can be configured using standard NSubstitute calls.
The solution is simply to use Returns and ReturnsForAnyArgs as I mentionned but it is essential that this newly created substitute is not used directly in the definition of a second substitute as it was the case when accessing the RequestId
.
Note the line var requestId = t.First().Files.First().RequestId;
that is now outside of the new Result()
definition.
public void MyTest()
{
IFixture fixture = new Fixture().Customize(new AutoNSubstituteCustomization() { ConfigureMembers = true });
var t = fixture.Create<ITransaction>();
t.Files.Returns(fixture.CreateMany<FileDef>(2).ToList());
t.Comments.Returns(fixture.CreateMany<Comment>(5).ToList());
var service1 = Substitute.For<ITransactionsSvc>();
service1.GetTransactions().ReturnsForAnyArgs(t);
var requestId = t.First().Files.First().RequestId;
var service2 = Substitute.For<IRequestsSvc>();
service2.GetRequest(default).ReturnsForAnyArgs(
new Result(){
TransactionId = requestId
}
);
}