bryan
bryan

Reputation: 1051

When to use Mock's Callback versus Return?

I have, what I think, is a pretty straight forward setup in which a search type is created and passed through a service layer and into a repository where a list of a domain type is returned. The search type does nothing but construct an expression tree in the repository method and basically the results from the database come back. Pretty simple

The repository interface:

public interface IDoNotSolicitRepo 
{
    IList<DNSContract> SelectWithCriteria(DNS_Search searchriteria); 
}

The service implementing the repository:

public class DoNotSolicitService : BaseBLLService, IDoNotSolicitService
{
    private readonly IDoNotSolicitRepo repo;
    private readonly IPartnerService partnerService;
    private readonly IDoNotSolicitReasonService dnsReasonSvc;
    public DoNotSolicitService(IDoNotSolicitRepo _repo, IPartnerService _partnerSvc, IDoNotSolicitReasonService _dnsReasonSvc)
    {
        repo = _repo;
        partnerService = _partnerSvc;
        dnsReasonSvc = _dnsReasonSvc;
    }

    public ServiceResult<DNSContract> SelectWithCriteria(DNS_Search searchriteria)
    {
        var results = repo.SelectWithCriteria(searchriteria);

        return ReturnServiceResult(results);
    }
}

I'm working on learning Moq with this project and I can't figure out if I'm supposed to use a Callback() or a Return(). I get the overall points of both, but neither seem to work properly for me at this moment.

The test:

[Test]
public void SelectWithCriteria_FirstName()
{
    mockRepository.Setup(mr => mr.SelectWithCriteria(It.IsAny<DNS_Search>()))
        .Returns((IList<DNSContract> records) => new List<DNSContract>
                                                     {
                                                         new DNSContract {FirstName = "unit", LastName = "test"},
                                                         new DNSContract {FirstName = "moq", LastName = "setup"}
                                                     });

    dnsSvc = new DoNotSolicitService(mockRepository.Object, new PartnerServiceStub(), new DoNotSoicitReasonServiceStub());

    var result = dnsSvc.SelectWithCriteria(new DNS_Search { FirstName = "unit" });

    Assert.IsNotNull(result);
    Assert.IsTrue(result.Data.Any());
}

The error:

System.ArgumentException was unhandled by user code


 Message=Object of type 'EP.Rest.Common.RestHelpers.DNS_Search' cannot be converted to type 'System.Collections.Generic.IList`1[EP.Rest.Domain.Contracts.DNSContract]'.

Now, I've read that the Returns() method returns the type passed in, so I can see that's the cause of that error. But in the real world I want the different type returned. I've attempted to create a callback delegate but none of that felt right.

Upvotes: 5

Views: 8755

Answers (1)

Shaun Wilde
Shaun Wilde

Reputation: 8358

Just drop the lambda on .Returns i.e.

.Returns(new List<DNSContract>());

Your original is passing in arguments from your method to the returns to parameterize the results eg if pulling from a source that can return different data depending on input.

Or

.Returns<IList<DNSContract>>(new List<DNSContract>(){...});

Upvotes: 3

Related Questions