noobie
noobie

Reputation: 2607

Issues with mocking methods using Moq

I have the following class that has two static methods Retrieve and RetrieveWithQuery. Below the classes listed here, I have included a snippet of the test. All but the last assert of the test fails with the following message:

Failed TestMethod2 MoqTest Assert.AreEqual failed. Expected:. Actual:<(null)>.

I understand that the problem may be that the query that I setup in the mock is a different instance from the query used in the RetrieveWithQuery method. And that is why is would be returning null.

In a perfect world I would simply re-factor the service class, unfortunately I am working with legacy code that is already production. The goal is to first complete tests, then re-factor code and run regression testing before updating production environment.

Is there a workaround or different way to test this?

public class MyService  
{
    public virtual string RetrieveMethod(string account)
    {
        if (account == "The abc company")
        {
            return "Peter Smith";
        }

            return "John Doe";
    }

    public virtual string RetrieveMethod(MyQuery query)
    {
        return RetrieveMethod(query.QueryString);   
    }

    public static string Retrieve(MyService service, string value)
    {
        return service.RetrieveMethod(value);
    }

    public static string RetrieveWithQuery(MyService service, string value)
    {
        var query = new MyQuery
        {
            QueryString = value
        };

        return service.RetrieveMethod(query);
    }

}

public class MyQuery
{
    public string QueryString;
}



    [TestMethod]
    public void TestMethod2()
    {
        var mockService = new Mock<MyService>();

        const string company = "The abc company";
        const string expectedContact = "Peter Smith";

        var queryAccount = new MyQuery
                        {
                            QueryString = company
                        };

        // Setup base retrieve
        mockService.Setup(myServ => myServ.RetrieveMethod(company)).Returns(expectedContact);

        // Setup base retrieve with query
        mockService.Setup(myServ => myServ.RetrieveMethod(queryAccount)).Returns(expectedContact);

        // test base retrieve with query - PASS
        Assert.AreEqual(expectedContact, mockService.Object.RetrieveMethod(queryAccount));

        // test static method retrieve - PASS
        Assert.AreEqual(expectedContact, MyService.Retrieve(mockService.Object, company));

        // test static method retrieve with query - FAIL
        Assert.AreEqual(expectedContact, MyService.RetrieveWithQuery(mockService.Object, company));
    }

Upvotes: 1

Views: 132

Answers (1)

tallseth
tallseth

Reputation: 3675

Try this for your setup:

    // Setup base retrieve with query
    mockService.Setup(myServ => myServ.RetrieveMethod(It.Is<Query>(q=>q.QueryString == queryAccount.QueryString)).Returns(expectedContact);

Or you could overload on Equals for Query so that the Query that gets created is equal to expectedQuery.

The Moq QuickStart page has good examples of this and more which should help a lot.

Upvotes: 1

Related Questions