'All invocation on the mock must have a corresponding setup when setting string parameter

I have a simple method I am testing. When I run the test I get the error

"All invocation on the mock must have a corresponding setup"

on the last line

dataField.DefaultValue = orderNumber.ToString();

What would cause this?

I am just setting a field.

void IUtilities.SetOrderIdInDocumentMetaData(Document document, int orderNumber)
{
    DataField dataField = null;
    if (document.DataFields.IsPresent(ORDER_ID) == false)
    {
        dataField = document.DataFields.Add(ORDER_ID, AppDefault: false, DocDefault: false);
    }
    else
    {
        dataField = document.DataFields[ORDER_ID];
    }

    dataField.DefaultValue = orderNumber.ToString();
}

This is my unit test code.

[TestMethod]
public void Utilities_SetOrderIdInDocumentMetaData_SetNew()
        {
    string orderNumber = "1";
    int orderId = 1;

    corelDocument
        .Setup(s => s.DataFields.IsPresent(ORDER_ID))
        .Returns(false);

    corelDocument
        .Setup(s => s.DataFields.Add(ORDER_ID, null, false, false, false))
        .Returns(corelDataField.Object);

    corelDataField
        .Setup(s => s.DefaultValue)
        .Returns(orderNumber);

    Utilities.SetOrderIdInDocumentMetaData(corelDocument.Object, orderId);

    Assert.AreEqual(orderNumber, corelDataField.Object.DefaultValue);
}


Solution 1:[1]

If you want the mock's properties to retain assigned values, call SetupAllProperties

corelDataField.SetupAllProperties();

Your initial setup

corelDataField
    .Setup(s => s.DefaultValue)
    .Returns(orderNumber);

was only for getting the value, not setting it.

When you call

dataField.DefaultValue = orderNumber.ToString();

You are trying to set the property. Which the mock was not setup to handle.

Reference : Moq Quickstart

Solution 2:[2]

You are using a "Strict Mock" which is count as bad practice(except rare cases). The reason it is a bad practice is quite simple; Your UT became too depends on the implementation instead of verifying behavior of specific case.

Just remove MockBehavior.Strict from the mock initialization and then everything will work fine.

Solution 3:[3]

I have the following interface.

public interface IEventGridTopic
{
  Task PublishCompanyOnboarding(string companyName);
}

I have setup the Moq like this.

eventGridTopicMock.Setup(eventGridTopic => eventGridTopic.PublishCompanyOnboarding(It.IsAny<string>()));

Now I get the following message as the test fails.

IEventGridTopic.PublishCompanyOnboarding("asdfasdf") invocation failed with mock behavior Strict. Invocation needs to return a value and therefore must have a corresponding setup that provides it.

So return value is not configured. I did not configure it as I thought its returning Task, means void, nothing.

So I changed it to the following to make it pass.

eventGridTopicMock.Setup(eventGridTopic => eventGridTopic.PublishCompanyOnboarding(It.IsAny<string>())).Returns(Task.CompletedTask);

Add Returns(Task.CompletedTask)

Reference. Moq with Task await

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Old Fox
Solution 3 VivekDev