user3324848
user3324848

Reputation: 181

Mocking a method in the same class

Here is my implementation of a webRequest Post method for the survey monkey api oauth token.I am writing unit test for the below code.

public string GetSurveyMonkeyToken(string apiKey, string clientSecret, string tempAuthCode, string redirectUri, string clientId)
{
    if (!VerifyRedirectedTempCode(tempAuthCode))//this method is in the same class which checks the temp code valid(true) or not(false)
    {
        return null;
    }
    else
    {
        WebRequestForTokenOfSurveyMonkey = GetWebRequestForHttpPostOfSurveyMonkeyToken(apiKey, clientSecret, tempAuthCode, redirectUri, clientId);
        using (HttpWebResponse responseHttpPostForToken = GetResponse(WebRequestForTokenOfSurveyMonkey))//Getresponse method is in the same class which returns this (HttpWebResponse)webRequestObject.GetResponse()
        {
            string tokenJson = new StreamReader(responseHttpPostForToken.GetResponseStream()).ReadToEnd();
            AccessToken accesstokenObj = JsonConvert.DeserializeObject<AccessToken>(tokenJson);
            string accessTokenSurvey = accesstokenObj.access_token.ToString();
            return (accesstokenObj.access_token.ToString());
        }
    }
}

Now the above code is working fine but I have a problem writing unit tests to this method.below are my unit test to them,One test where I mock my method to return false works fine it returns null.

[Test]
public void GetSurveyMonkeyTokenTestWithValidTempCode()
{
    var mockedSurveyMonkeyToken = new Moq.Mock<SurveyMonkeyAPIService>();
    mockedSurveyMonkeyToken.CallBase = true;
    mockedSurveyMonkeyToken.Setup(a => a.VerifyRedirectedTempCode(It.IsAny<string>())).Returns(true);
    var mockRequest = mockedSurveyMonkeyToken.Object.GetWebRequestForHttpPostOfSurveyMonkeyToken(TestData.TestData.SampleApiKey, TestData.TestData.SampleClientSecret, TestData.TestData.SampleTempAuthCode, TestData.TestData.SampleRedirectUri, TestData.TestData.SampleClientId);
    mockedSurveyMonkeyToken.VerifyAll();
}

The error for this test method is Moq.MockVerificationException : The following setups were not matched: SurveyMonkeyAPIService a => a.VerifyRedirectedTempCode(It.IsAny())

What is the problem in my Tests.Did I write the test methods properly.I am writing the httpwebrequest test methods for the first time.

Upvotes: 2

Views: 4166

Answers (2)

mezoid
mezoid

Reputation: 28690

I think you might be applying the concept of Mocking incorrectly.

The purpose of Mocking is supposed to be used to mock out the dependencies of a class under test.

Unfortunately, what you appear to be doing is mocking out the methods of the class that is under test. This is an easy mistake to make when you are first starting out. However, doing so defeats the whole purpose of unit testing since your aim should be to independently test the functionality of the class. If you mock out the methods of the class, you would effectively be replacing the implementation you are attempting to test.

In looking at your unit test, you will notice that your entire test revolves around the mock var mockedSurveyMonkeyToken = new Moq.Mock<SurveyMonkeyAPIService>();.

What you want to do is determine what your class's dependencies are, and then mock them out so that you can control what they do as you test the public methods of the class.

If SurveyMonkeyAPIService is the dependency, then you would pass that mock to the class under test. (e.g. var cut = new MyClassUnderTest(surveyMonkeyAPIServiceMock).

However, if SurveyMonkeyAPIService is the class under test as I suspect it is, then you will need to create an instance of this class in your test and pass in a mock of any dependencies. I think your dependency would be for HttpWebResponse webRequestObject.

Your test would have something like the following:

var sm = new SurveyMonkeyAPIService(webRequestObjectMock); //create the class under test. Arrange
sm.GetSurveyMonkeyToken(...); //exercise the class under test. Act
webRequestObjectMock.Verify(...); //verify that the mock was exercised as expected. Assert

Note: Arrange, Act, Assert are the three steps of Triple A unit testing...

See this question for an example of how to mock a HttpWebResponse dependency.

Upvotes: 3

Joe Taylor
Joe Taylor

Reputation: 2175

I agree with mezoid that your testing is pretty unorthodox. The reason your test is failing is that you're calling directly into the GetWebRequestForHttpPostOfSurveyMonkeyToken method, rather than the GetSurveyMonkeyToken method. GetWebRequestForHttpPostOfSurveyMonkeyToken presumably doesn't call VerifyRedirectedTempCode because you've called that in GetSurveyMonkeyToken.

To get the test to pass, probably you can change the line

var mockRequest = mockedSurveyMonkeyToken.Object.GetWebRequestForHttpPostOfSurveyMonkeyToken(TestData.TestData.SampleApiKey, TestData.TestData.SampleClientSecret, TestData.TestData.SampleTempAuthCode, TestData.TestData.SampleRedirectUri, TestData.TestData.SampleClientId);

to

var mockRequest = mockedSurveyMonkeyToken.Object.GetSurveyMonkeyToken(TestData.TestData.SampleApiKey, TestData.TestData.SampleClientSecret, TestData.TestData.SampleTempAuthCode, TestData.TestData.SampleRedirectUri, TestData.TestData.SampleClientId);

But I would think about redesigning your application a bit to separate out the unit you want to test. Maybe you should post a question to the codereview stackexchange site.

Upvotes: 1

Related Questions