【问题标题】:Mocking a method in the same class模拟同一类中的方法
【发布时间】:2014-04-08 07:52:07
【问题描述】:

这是我对调查猴子 api oauth 令牌的 webRequest Post 方法的实现。我正在为以下代码编写单元测试。

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());
        }
    }
}

现在上面的代码工作正常,但是我在为这个方法编写单元测试时遇到问题。下面是我对它们的单元测试,我模拟我的方法返回 false 的一个测试工作正常,它返回 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();
}

此测试方法的错误是 Moq.MockVerificationException :以下设置不匹配: SurveyMonkeyAPIService a => a.VerifyRedirectedTempCode(It.IsAny())

我的Tests有什么问题。我写的测试方法是否正确。我是第一次写httpwebrequest测试方法。

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    我认为您可能错误地应用了 Mocking 的概念。

    Mocking 的目的应该是用来模拟被测类的依赖

    不幸的是,您似乎在模拟正在测试的类的方法。当您刚开始时,这是一个容易犯的错误。但是,这样做违背了单元测试的全部目的,因为您的目标应该是独立测试类的功能。如果你模拟出类的方法,你将有效地替换你试图测试的实现。

    在查看您的单元测试时,您会注意到您的整个测试都围绕着模拟 var mockedSurveyMonkeyToken = new Moq.Mock&lt;SurveyMonkeyAPIService&gt;();

    您要做的是确定您的类的依赖项是什么,然后将它们模拟出来,以便您可以在测试类的公共方法时控制它们的作用。

    如果SurveyMonkeyAPIService 是依赖项,那么您可以将该模拟传递给被测类。 (例如var cut = new MyClassUnderTest(surveyMonkeyAPIServiceMock)

    但是,如果SurveyMonkeyAPIService 是我怀疑的被测类,那么您将需要在测试中创建此类的实例并传入任何依赖项的模拟。我认为你的依赖是HttpWebResponse webRequestObject

    您的测试将具有以下内容:

    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
    

    注意:Arrange、Act、Assert 是 Triple A 单元测试的三个步骤...

    有关如何模拟 HttpWebResponse 依赖项的示例,请参阅 this question

    【讨论】:

    • 谢谢,我会考虑的,是的,我是第一次写单元测试。
    【解决方案2】:

    我同意 mezoid 的观点,即您的测试非常不正统。您的测试失败的原因是您直接调用了GetWebRequestForHttpPostOfSurveyMonkeyToken 方法,而不是GetSurveyMonkeyToken 方法。 GetWebRequestForHttpPostOfSurveyMonkeyToken 可能不会调用 VerifyRedirectedTempCode,因为你已经在 GetSurveyMonkeyToken 中调用了它。

    为了让测试通过,也许你可以换行

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

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

    但我会考虑重新设计您的应用程序以分离出您要测试的单元。也许您应该向 codereview stackexchange 站点发布问题。

    【讨论】:

      猜你喜欢
      • 2017-01-05
      • 2011-08-13
      • 2016-07-17
      • 1970-01-01
      • 2015-06-13
      • 2018-01-09
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多