I have the following unit test that is testing predicate logic in a repository (Note: mockOpportunityRepository.Setup
):
[Test]
public void GetFollowedByUserIdShouldGetTheUsersFollowedOpportunitiesFromOpportunityFollowRepositoryAndThenGetThoseFollowedOpportunities()
{
const int ExpectedOpportunityId = 9;
var testOpportunities = new List<Domain.EF.Opportunity>()
{
OpportunityBuilder.Default().WithId(1).Build(),
OpportunityBuilder.Default().WithId(2).Build(),
OpportunityBuilder.Default().WithId(ExpectedOpportunityId).Build(),
};
var actualOpportunities = new List<Opportunity>();
var expectedOpportunityFollows = new List<OpportunityFollow> { new OpportunityFollow { OpportunityFollowId = 1, OpportunityId = ExpectedOpportunityId, UserId = UserId } };
mockOpportunityFollowRepository.Setup(x => x.GetByUserId(UserId)).ReturnsAsync(expectedOpportunityFollows);
mockOpportunityRepository.Setup(
s =>
s.GetAsync(
It.IsAny<Expression<Func<Domain.EF.Opportunity, bool>>>(),
It.IsAny<Func<IQueryable<Domain.EF.Opportunity>, IOrderedQueryable<Domain.EF.Opportunity>>>(),
It.IsAny<int?>(),
It.IsAny<int>()))
.Callback<
Expression<Func<Domain.EF.Opportunity, bool>>,
Func<IQueryable<Domain.EF.Opportunity>,
IOrderedQueryable<Domain.EF.Opportunity>>,
int?,
int>((queryParam, sortParam, takeParam, skipParam) =>
{
var func = queryParam.Compile();
actualOpportunities = testOpportunities.Where(func).ToList();
});
var results = sut.GetFollowedByUserId(UserId);
mockOpportunityFollowRepository.Verify(x => x.GetByUserId(UserId), Times.Once);
actualOpportunities.Count.Should().Equals(1);
actualOpportunities[0].OpportunityId.Should().Equals(ExpectedOpportunityId);
}
I have several tests like this all utilising the same bulky mockOpportunityRepository.Setup
and wanted to refactor it into one re-useable place. Essentially the setup has a callback which runs an anonymous function. The anon function compiles the query parameters and executes them against a test list of opportunities. The outer test function needs the result of this filter to Assert the predicate logic.
If I try to move the mockOpportunityRepository.Setup
into a separate function and try to output the actualOpportunities
by reference I get a compiler error that ref and out parameters are not allowed in anonymous method body. I'm not very knowledgeable on functions and am sure it can be done.
Can anyone refactor this and suggest a way of moving the mockOpportunityRepository.Setup
out of the test to make it reusable yet somehow get the results of the anonymous function (actualOpportunities
) back to the calling test?