Home > Enterprise >  Moq doesn't match methods. Moq.MockException: All invocations on the mock must have a correspon
Moq doesn't match methods. Moq.MockException: All invocations on the mock must have a correspon

Time:03-17

Moq doesn't match the mocked method.

Exception:

Exception thrown: 'Moq.MockException' in Moq.dll: 'IMongoRepository.FindByVrcId("b4cb3139-90aa-4477-979b-d893e3317386") invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.'

This is my unit test:

public class OfferHandlerTest : TestBase
{
    Mock<IMongoRepository> repositoryMock = new Mock<IMongoRepository>(MockBehavior.Strict);
    OfferHandler? offerHandler;

    [Fact]
    public void HandleTest()
    {
        JObject? offerFullDocument = null;
        using (var sr = new StreamReader("Data/offer_full_document.json"))
        {
            var reader = new JsonTextReader(sr);
            offerFullDocument = JObject.Load(reader);
        }

        var kafkaPayload = new KafkaMessagePayloadSourceConnector();
        kafkaPayload.OperationType = Constants.Mongo_OperationType_Update;
        kafkaPayload.FullDocument = offerFullDocument;

        OfferService service = new OfferService(repositoryMock.Object);
        offerHandler = new OfferHandler(service, this.ServiceConfiguration);

        offerHandler.Handle(kafkaPayload);

        DHOffer offer = new DHOffer();
        offer.Version = 1;

        // THIS SETUP FAILS
        repositoryMock.Setup(s => s.FindByVrcId<DHOffer>(It.IsAny<string>())).Returns(It.IsAny<DHOffer>());

        repositoryMock.Verify(s => s.FindAndUpdate<DHOffer>(It.IsAny<DHOffer>()), Times.Once);
    }
}

This is the handle method:

public void Handle(KafkaMessagePayloadSourceConnector kafkaPayload)
{
    VRCOffer offer = kafkaPayload!.FullDocument!.ToObject<VRCOffer>()!;

    if (kafkaPayload!.OperationType!.Equals(Constants.Mongo_OperationType_Update))
    {
        offerService.updateOfferStatus(OfferMapper.MapToDataHubModel(offer), offer.MasterId);
    }
}

And finally the service method:

public class OfferService
{
    private readonly IMongoRepository offerRepository;

    public OfferService(IMongoRepository offerRepository)
    {
        this.offerRepository = offerRepository;
    }
    
    internal void updateOfferStatus(DHOffer offer, string vrcMasterId)
    {
        // THIS SHOULD RETURN MOCKED OBJECT
        DHOffer existingOffer = offerRepository.FindByVrcId<DHOffer>(vrcMasterId);
        existingOffer.ModifiedDate = DateTime.Now.ToString();
        existingOffer.AdditionalInformation.Status = offer?.AdditionalInformation?.Status!;

        offerRepository.FindAndUpdate(existingOffer);
    }
}

I tried using It.IsAny<DHOffer>() in the Return() method but I get the same exception.

CodePudding user response:

Your issue is that you are running the Moq setup after the mocked object has been used. By then it's already too late. You just need to run the .Setup(...) commands at the start.

It's also worth noting that using a shared mock can be problematic if multiple tests need the setups to be different. Some tools can run tests in parallel which may screw things up, or in a different order which can cause things to be more brittle.

  • Related