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

10,465

Solution 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

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.

Share:
10,465

Related videos on Youtube

Ben Hoffman
Author by

Ben Hoffman

Web Developer based out of Cuyahoga Falls, OH I specialize in Web Development with C# and SQL Server. I also do some Microsoft Dynamics AX development.

Updated on September 15, 2022

Comments

  • Ben Hoffman
    Ben Hoffman over 1 year

    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);
    }
    
  • Stuart Dobson
    Stuart Dobson about 4 years
    This is a subjective answer (it's often not bad practice) that doesn't explain the implications of turning this off. Yes it might fix the problem but is a sledgehammer solution and you should understand what you are giving up when doing it.
  • Old Fox
    Old Fox over 3 years
    @stuartdotnet strict mock is raising an exception when any call which don't have expectation is being called. when you are using it than usually you test more than one thing and make your UT to not testing only behavior. In most cases over time it will cause you more troubles than help due to the fact that live code is changing and the UT will fall although the behavior wasn't change and without it you weren't touch your UT at all. This is usually where companies who tried UTs for the first time fall.