Facebook C#SDKは、HttpWebRequestとHttpWebResponse全体を嘲笑するシナリオをサポートしています。実際には、ユニットテストで内部的に使用しています。そのため、Facebook C#SDKのすべてのコードが実際に実行され、結果は常に同じになります。 https://github.com/facebook-csharp-sdk/facebook-csharp-sdk/blob/v5/Source/Facebook.Tests/TestExtensions.csこれらのテストをまだv6に移行していないので、v5ブランチでこれらのテストをチェックする必要があります。
v5の場合、保護されたCreateHttpWebRequest
メソッドをFacebookClientでオーバーライドする必要があります。
ここでは、インターネットに接続していない場合のv5の例を示します。 HttpWebRequestWrapper、HttpWebResponseWrapper、WebExceptionWrapperの3つの隠しクラスが必要です。
public static void NoInternetConnection(this Mock<Facebook.FacebookClient> facebookClient, out Mock<HttpWebRequestWrapper> mockRequest, out Mock<WebExceptionWrapper> mockWebException)
{
mockRequest = new Mock<HttpWebRequestWrapper>();
mockWebException = new Mock<WebExceptionWrapper>();
var mockAsyncResult = new Mock<IAsyncResult>();
var request = mockRequest.Object;
var webException = mockWebException.Object;
var asyncResult = mockAsyncResult.Object;
mockRequest.SetupProperty(r => r.Method);
mockRequest.SetupProperty(r => r.ContentType);
mockRequest.SetupProperty(r => r.ContentLength);
mockAsyncResult
.Setup(ar => ar.AsyncWaitHandle)
.Returns((ManualResetEvent)null);
mockWebException
.Setup(e => e.GetResponse())
.Returns<HttpWebResponseWrapper>(null);
mockRequest
.Setup(r => r.GetResponse())
.Throws(webException);
mockRequest
.Setup(r => r.EndGetResponse(It.IsAny<IAsyncResult>()))
.Throws(webException);
AsyncCallback callback = null;
mockRequest
.Setup(r => r.BeginGetResponse(It.IsAny<AsyncCallback>(), It.IsAny<object>()))
.Callback<AsyncCallback, object>((c, s) =>
{
callback = c;
})
.Returns(() =>
{
callback(asyncResult);
return asyncResult;
});
var mockRequestCopy = mockRequest;
var mockWebExceptionCopy = mockWebException;
facebookClient.Protected()
.Setup<HttpWebRequestWrapper>("CreateHttpWebRequest", ItExpr.IsAny<Uri>())
.Callback<Uri>(uri =>
{
mockRequestCopy.Setup(r => r.RequestUri).Returns(uri);
mockWebExceptionCopy.Setup(e => e.Message).Returns(string.Format("The remote name could not be resolved: '{0}'", uri.Host));
})
.Returns(request);
}
次のようにテストを書くことができます。私たちはHttpWebRequestのとHttpWebResponseの方がはるかに簡単にからかってきたV6で
[Fact]
public void SyncWhenThereIsNotInternetConnectionAndFiddlerIsNotOpen_ThrowsWebExceptionWrapper()
{
var mockFb = new Mock<FacebookClient> { CallBase = true };
Mock<HttpWebRequestWrapper> mockRequest;
Mock<WebExceptionWrapper> mockWebException;
mockFb.NoInternetConnection(out mockRequest, out mockWebException);
Exception exception = null;
try
{
var fb = mockFb.Object;
fb.Get(_parameters);
}
catch (Exception ex)
{
exception = ex;
}
mockFb.VerifyCreateHttpWebRequest(Times.Once());
mockRequest.VerifyGetResponse();
mockWebException.VerifyGetReponse();
Assert.IsAssignableFrom<WebExceptionWrapper>(exception);
}
。
HttpWebRequestWrapper
およびHttpWebReponseWrapper
を継承して、カスタムHttpWebRequestおよびHttpWebResponseを作成します。
次に、Facebook C#SDKのデフォルトのhttp Web要求ファクトリを変更します。ここに、デフォルト工場のサンプルがあります。
FacebookClient.SetDefaultHttpWebRequestFactory(uri => new HttpWebRequestWrapper((HttpWebRequest)WebRequest.Create(uri)));
FacebookクライアントインスタンスごとにHttpWebRequestFactorを変更する場合は、次のコードを使用します。
var fb = new FacebookClient();
fb.HttpWebRequestFactory = uri=> new MyHttpWebRequestWrapper(uri);
注:HttpWebRequestWrapper、HttpWebResponseWrapper、WebExceptionWrapper、FacebookClient.SetDefaultHttpWebRequestFactoryとFacebookClient。HttpWebRequestFactoryには属性[EditorBrowsable(EditorBrowsableState.Never)]
があるため、インテリセンスでは表示されないことがあります。
実際にはFacebookのC#sdkテストの一部で、あなたのアプリユニットテストではないと言われるインターネット接続はありません。 sdkは、インターネット接続が存在しない場合、常にWebExceptionWrapperをスローし、アプリケーションユニットテストは実際にWebExceptionWrapper例外を処理し、httpwebrequestとhttpwebresponse全体を嘲笑しないことを保証する必要があります。
ありがとう!それは私が探していたものです。 –