I have this class:
public class RestClient { public RestClient() { } protected virtual HttpWebRequest CreateHttpWebRequest(Uri uri) { return (HttpWebRequest)HttpWebRequest.Create(uri); } /// <summary> /// Perform a http POST request in order to push data to server /// </summary> /// <param name="uri">End Point Uri</param> /// <param name="data">Data to be transmitted</param> /// <returns></returns> /// public long PostRequest(Uri uri,string data) { try { HttpWebRequest request = CreateHttpWebRequest(uri); //(HttpWebRequest)HttpWebRequest.Create(uri); request.Method = "POST"; request.ContentType = "application/json"; System.Text.UTF8Encoding encoding = new UTF8Encoding(); byte[] bytes = encoding.GetBytes(data); using (Stream requestStream = request.GetRequestStream()) { //Transmit data requestStream.Write(bytes, 0, bytes.Length); requestStream.Flush(); requestStream.Close(); } //Get the Response from the server using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.NoContent) { throw new Exception(String.Format( "Server error (HTTP {0}: {1}).", response.StatusCode, response.StatusDescription)); } } return request.ContentLength; } catch (Exception e) { throw e; } } } And would like to Unit test (using nunit) the PostRequest Method.
Doing some research, I could found some way to mock the HttpWebRequest in this post (Is it possible to mock out a .NET HttpWebResponse?) and a way to inject it into the class in this post (How to unit test a method with HttpWebRequest/Response dependencies).
However, when I tried to test my method I got this error:
System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.IHttpWebRequestProxy' to type 'System.Net.HttpWebRequest'. in this line of my test
client.HttpWebRequestFake = (HttpWebRequest)factory.Object.Create("http://127.0.0.1"); That is my test code:
public class TesableRestClient : RestClient { public HttpWebRequest HttpWebRequestFake { get; set; } protected override HttpWebRequest CreateHttpWebRequest(Uri url) { if (HttpWebRequestFake != null) return HttpWebRequestFake; return base.CreateHttpWebRequest(url); } } [TestFixture] public class TransferWebRequestTest { [Test] public void TestPostResquest() { string expectedContent = "Content"; var expectedBytes = Encoding.UTF8.GetBytes(expectedContent); var responseStream = new MemoryStream(); responseStream.Write(expectedBytes, 0, expectedBytes.Length); responseStream.Seek(0, SeekOrigin.Begin); var response = new Mock<IHttpWebResponse>(); response.Setup(c => c.GetResponseStream()).Returns(responseStream); var request = new Mock<IHttpWebRequest>(); request.Setup(c => c.GetResponse()).Returns(response.Object); var factory = new Mock<IHttpWebRequestFactory>(); factory.Setup(c => c.Create(It.IsAny<string>())) .Returns(request.Object); TesableRestClient client = new TesableRestClient(); client.HttpWebRequestFake = (HttpWebRequest)factory.Object.Create("http://127.0.0.1"); // DoStuff call the url with a request and then processes the long bytesSent = client.PostRequest(new Uri("http://127.0.0.1"), expectedContent); Assert.AreEqual(expectedBytes, bytesSent); } The HttpWebRequest/Response is this:
public interface IHttpWebRequest { // expose the members you need string Method { get; set; } string ContentType { get; set; } long ContentLength { get; set; } IHttpWebResponse GetResponse(); } public interface IHttpWebResponse : IDisposable { // expose the members you need HttpStatusCode StatusCode { get; } string StatusDescription { get;} Stream GetResponseStream(); } public interface IHttpWebRequestFactory { IHttpWebRequest Create(string uri); } // barebones implementation public class HttpWebRequestFactory : IHttpWebRequestFactory { public IHttpWebRequest Create(string uri) { return new WrapHttpWebRequest((HttpWebRequest)WebRequest.Create(uri)); } } public class WrapHttpWebRequest : IHttpWebRequest { private readonly HttpWebRequest _request; public WrapHttpWebRequest(HttpWebRequest request) { _request = request; } public string Method { get { return _request.Method; } set { _request.Method = value; } } public string ContentType { get { return _request.ContentType; } set { _request.ContentType = value; } } public long ContentLength { get { return _request.ContentLength; } set { _request.ContentLength = value; } } public IHttpWebResponse GetResponse() { return new WrapHttpWebResponse((HttpWebResponse)_request.GetResponse()); } } public class WrapHttpWebResponse : IHttpWebResponse { private HttpWebResponse _response; public WrapHttpWebResponse(HttpWebResponse response) { _response = response; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (disposing) { if (_response != null) { ((IDisposable)_response).Dispose(); _response = null; } } } public Stream GetResponseStream() { return _response.GetResponseStream(); } public HttpStatusCode StatusCode { get { return _response.StatusCode; } } public string StatusDescription { get { return _response.StatusDescription; } } } Any idea of how I could solve this?
Thank you
WrapHttpWebRequestis not of typeHttpWebRequest.