以下是我对调查猴子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 =&gt; a.VerifyRedirectedTempCode(It.IsAny())
我的测试中出现了什么问题。我正确地编写了测试方法。我是第一次编写httpwebrequest测试方法。
答案 0 :(得分:3)
我认为你可能错误地应用了Mocking的概念。
Mocking的目的应该用于模拟被测试类的 依赖 。
不幸的是,您似乎正在做的是模拟正在测试的类的方法。当你刚开始时,这是一个容易犯的错误。但是,这样做会破坏单元测试的整个目的,因为您的目标应该是独立测试类的功能。如果你模拟了类的方法,你将有效地替换你试图测试的实现。
在查看单元测试时,您会发现整个测试围绕模拟var mockedSurveyMonkeyToken = new Moq.Mock<SurveyMonkeyAPIService>();
进行。
您要做的是确定您的类的依赖关系,然后将其模拟出来,以便您可以在测试类的公共方法时控制它们执行的操作。
如果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
注意:安排,行动,断言是Triple A单元测试的三个步骤......
有关如何模拟HttpWebResponse依赖关系的示例,请参阅this question。
答案 1 :(得分:1)
我同意mezoid你的测试非常不正统。您的测试失败的原因是您直接调用GetWebRequestForHttpPostOfSurveyMonkeyToken
方法,而不是GetSurveyMonkeyToken
方法。 GetWebRequestForHttpPostOfSurveyMonkeyToken
可能不会致电VerifyRedirectedTempCode
,因为您已在GetSurveyMonkeyToken
中致电{1}}。
要让测试通过,可能您可以更改行
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网站发布一个问题。