RestSharp Unit Test NUnit Moq RestResponse null reference exception - c#

I'm having some challenges trying to use Moq with RestSharp. Maybe it's it my misunderstanding of Moq but for some reason I keep on getting a null reference exception when trying to Mock a RestResponse.
Here is my unit test.
[Test]
public void GetAll_Method_Throws_exception_if_response_Data_is_Null()
{
var restClient = new Mock<IRestClient>();
restClient.Setup(x => x.Execute(It.IsAny<IRestRequest>()))
.Returns(new RestResponse<RootObjectList>
{
StatusCode = HttpStatusCode.OK,
Content = null
} );
var client = new IncidentRestClient(restClient.Object);
Assert.Throws<Exception>(() => client.GetAll());
}
Here is my actually implementation:
public class IncidentRestClient : IIncidentRestClient
{
private readonly IRestClient client;
private readonly string url = "some url here";
public IncidentRestClient()
{
client = new RestClient { BaseUrl = new Uri(url) };
}
public RootObjectList GetAll()
{
var request = new RestRequest("api/now/table/incident", Method.GET) { RequestFormat = DataFormat.Json };
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
IRestResponse<RootObjectList> response = client.Execute<RootObjectList>(request);
if (response.Data == null)
throw new Exception(response.ErrorException.ToString());
return response.Data;
}
}
For some reason response object is null. Could it be I'm mocking the return object incorrectly?

For disclosure purposes, I am assuming that your IncidentRestClient has a constructor that takes an IRestClient instance as a parameter and uses it to set the client member.
It looks like, in your test, you are running Setup for a different overload of Execute than the one you are using. Instead of:
.Setup(x => x.Execute(
try:
.Setup(x => x.Execute<RootObjectList>(

Related

Mocked HttpClientFactory returns null when creating client

I am trying to unit test a service that uses the IHttpClientFactory with Nunit and NSubstitute for mocking.
The service I want to test looks like this
public class Movies : IMovies
{
private readonly IHttpClientFactory _httpClientFactory;
public Movies(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<MovieCollection> GetPopularMovies(int PageNumber = 1)
{
// Get an instance of HttpClient from the factpry that we registered
// in Startup.cs
var client = _httpClientFactory.CreateClient("Movie Api");
// Call the API & wait for response.
// If the API call fails, call it again according to the re-try policy
// specified in Startup.cs
var result =
await client.GetAsync($"movie/popular?api_key=<the_api_key>language=en-US&page={PageNumber}");
if (result.IsSuccessStatusCode)
{
// Read all of the response and deserialise it into an instace of
var content = await result.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<MovieCollection>(content);
}
return null;
}
}
When I run the test I get an error that says
System.NullReferenceException : Object reference not set to an instance of an object.
at MovieApi.Services.Movies.GetPopularMovies(Int...
Here is the test I am running.The error occurs only when I put the keyword await in the line
var result = await service.GetPopularMovies(1);
Check the Test code below:
[Test]
public async Task GetPopular_WhenCalled_ReturnOK()
{
//arrange
var moviecollection = new MovieCollection();
var httpClientFactoryMock = Substitute.For<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler(new HttpResponseMessage() {
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonConvert.SerializeObject(moviecollection), Encoding.UTF8, "application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);
// Act
var service = new Movies(httpClientFactoryMock);
var result = await service.GetPopularMovies(1);
//assert
Assert.IsNotNull(result);
}
The subject method under test calls
var client = _httpClientFactory.CreateClient("Movie Api");
but you configure the mock to return when CreateClient() is invoked.
httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);
which means that when testing and CreateClient("Movie Api") is invoked the mock wont know what to do and thus returns null, causing the next call to throw NRE
Setup the mock to behave as expected when the system under test is invoked.
//...
httpClientFactoryMock.CreateClient("Movie Api").Returns(fakeHttpClient);
//...

C# Mock IHttpclient & CreateClient

I have a function that I want to x-unit test, but it seems that I have to mock the CreateClient function? Whenever I debug it during testing it seems that the var client is equals to null. I am injecting the dependencies properly, I am sure of that. What I want to know is how to mock the CreateClient.
here is that function:
public async Task CreateMessageHistoryAsync(Message message)
{
//This seems to be giving a null value
var client = this.clientFactory.CreateClient(NamedHttpClients.COUCHDB);
var formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
Guid id = Guid.NewGuid();
var response = await client.PutAsync(id.ToString(), message, formatter);
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(await response.Content.ReadAsStringAsync());
}
}
here is the unit test, I am mocking the IHttpClient in a separate class and I am using that class.
[Collection("MockStateCollection")]
public class CreateMessageHistory
{
private readonly MockStateFixture mockStateFixture;
public CreateMessageHistory(MockStateFixture mockStateFixture)
{
this.mockStateFixture = mockStateFixture;
}
[Fact]
public async Task Should_NotThrowHttpRequestException_When_AMessageHistoryIsCreated()
{
var recipients = MockMessage.GetRecipients("Acc", "Site 1", "Site 2", "Site 3");
var message = MockMessage.GetMessage(recipients);
mockStateFixture
.MockMessageHistoryService
.Setup(service => service.CreateMessageHistoryAsync(message));
var messageHistoryService = new MessageHistoryService(
mockStateFixture.MockIHttpClientFactory.Object);
mockStateFixture.MockIHttpClientFactory.Object.CreateClient("CouchDB");
var task = messageHistoryService.CreateMessageHistoryAsync(message);
var type = task.GetType();
Assert.True(type.GetGenericArguments()[0].Name == "VoidTaskResult");
Assert.True(type.BaseType == typeof(Task));
await task;
//await Assert.IsType<Task>(messageHistoryService.CreateMessageHistoryAsync(message));
// await Assert.ThrowsAsync<HttpRequestException>(() => messageHistoryService.CreateMessageHistoryAsync(message));
}
}
it seems to me that I also need to mock the CreateClient class is it?
You should inject a mocked object for ClientFactory for which you have setup the CreateClient method.
// create the mock client
var httpClient = new Mock<IHttpClient>();
// setup method call for client
httpClient.Setup(x=>x.PutAsync(It.IsAny<string>()
, It.IsAny<Message>(),
, It.IsAny< JsonMediaTypeFormatter>())
.Returns(Task.FromResult(new HttpResponseMessage { StatusCode = StatusCode.OK}));
// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
.Returns(httpClient);
Then you have to pass the httpClientFactoryMock.Object to the constructor:
var messageHistoryService = new MessageHistoryService(httpClientFactoryMock.Object);
Update
In order to unit test HttpClient since it hasn't any interface you should wrap it in way as it is described here.
Specifically we have to arrange the http client as below:
// Mock the handler
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock.Protected()
// Setup the PROTECTED method to mock
.Setup<Task<HttpResponseMessage>>("PutAsync",
ItExpr.IsAny<String>(),
ItExpr.IsAny<Message>()
ItExpr.IsAny<MediaTypeFormatter>())
// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK
})
.Verifiable();
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri("http://test.com/"),
};
Now we should return the above httpClient when CreateClient is called.
// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
.Returns(httpClient);

Testing the result of HttpResponse.StatusCode

I've written an ErrorsController that as you can imagine, has pretty simple methods to continue to serve dynamic content in the case of an error, e.g. 500.
Now what I want to do is test that in that method, HttpResponseBase.StatusCode is set to a given number while executing this method, but for some reason, the StatusCode property is always 0. This includes when examining the property directly after setting it.
Controller
public ViewResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
const string PageTitle = "404 Page Not Found";
var viewModel = this.GetViewModel(PageTitle);
return this.View(viewModel);
}
GetViewModel does nothing other than setting properties on a view model
Test
[SetUp]
public void Setup()
{
this.httpContext = new Mock<HttpContextBase>();
this.httpResponse = new Mock<HttpResponseBase>();
this.httpContext.SetupGet(x => x.Response).Returns(this.httpResponse.Object);
this.requestContext = new RequestContext(this.httpContext.Object, new RouteData());
this.controller = new ErrorsController(this.contentRepository.Object);
this.controllerContext = new Mock<ControllerContext>(this.requestContext, this.controller);
this.controllerContext.SetupGet(x => x.HttpContext.Response).Returns(this.httpResponse.Object);
this.controller.ControllerContext = this.controllerContext.Object;
}
[Test]
public void Should_ReturnCorrectStatusCode_ForNotFoundAction()
{
this.controller.NotFound();
this.httpResponse.VerifySet(x => x.StatusCode = (int)HttpStatusCode.NotFound);
Assert.AreEqual((int)HttpStatusCode.NotFound, this.httpResponse.StatusCode);
}
Where am I going wrong here?
Just add this in your setup phase:
httpResponse.SetupAllProperties();
This being said, you probably don't need those 2 assertions:
this.httpResponse.VerifySet(x => x.StatusCode = (int)HttpStatusCode.NotFound);
Assert.AreEqual((int)HttpStatusCode.NotFound, this.httpResponse.StatusCode);
The first should be more than enough for your unit test.
I end up with an extension method for mocking HttpContext
public static class HttpContextExtensions
{
public static void MockHttpContext(this Controller controller)
{
var httpContextMock = new Mock<HttpContextBase>();
var requestMock = new Mock<HttpRequestBase>();
var responseMock = new Mock<HttpResponseBase>();
responseMock.SetupAllProperties();
requestMock.SetupAllProperties();
httpContextMock.Setup(x => x.Response).Returns(responseMock.Object);
httpContextMock.Setup(x => x.Request).Returns(requestMock.Object);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = httpContextMock.Object;
}
}
Usage:
someController.MockHttpContext()

How could I Mock this code?

I want to start mocking some code but I am unsure how to do it. I have read a few tutorials but I cannot apply it to my code (There maybe a reason behind it).
I am using NUnit and Moq.
(I have removed all other methods so I can just show you one).
Api Interface:
public interface IApiRequest
{
Task<T> ExecuteAsync<T>(RestRequest request);
}
Method I want to Mock:
public async Task<UpcomingMovies> GetUpcomingMovies(int page)
{
var request = new RestRequest
{
Resource = "movie/upcoming",
};
request.AddParameter("page", page.ToString());
request.AddParameter("language", "en");
var api = new ApiRequest();
return await api.ExecuteAsync<UpcomingMovies>(request);
}
I'm not sure how I can mock this.
Update:
Is this now a valid test?
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(new UpcomingMovies()));
If you want to mock the ExecutAsync method you can do it like this:
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(/** whatever movies **/));
if you want to mock for a particlur request, replace It.IsAny<RestRequest>() with a reference to your request.
To effectively test your class you need something like this:
public class MyClass
{
public MyClass(IApiRequest api)
{
this.api = api;
}
public async Task<UpcomingMovies> GetUpcomingMovies(int page)
{
var request = new RestRequest
{
Resource = "movie/upcoming",
};
request.AddParameter("page", page.ToString());
request.AddParameter("language", "en");
return await api.ExecuteAsync<UpcomingMovies>(request);
}
}
Test
[Test]
public async Task MyTest()
{
var expectedMovies = new UpcomingMovies(); // or whatever movies you need
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(expectedMovies));
var myClass = new MyClass(mock.Object);
var result = await myClass.GetUpcomingMovies(1);
Assert.IsTrue(expectedMovies == result);
}

In ServiceStack is it possible to mock the Request.OriginalRequest object for unit tests?

I'd like to make my ServiceStack service testable.
Presently I have:
[RequireFormsAuthentication]
public object Delete(DeleteRequest request)
{
var originalRequest = (HttpRequest)Request.OriginalRequest;
var identity = originalRequest.RequestContext.HttpContext.User.Identity;
return othercode(identity);
}
Where RequireFormsAuthentication is
public class RequireFormsAuthenticationAttribute : RequestFilterAttribute
{
public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
{
var originalRequest = (HttpRequest)req.OriginalRequest;
var identity = originalRequest.RequestContext.HttpContext.User.Identity;
if (!identity.IsAuthenticated)
{
res.StatusCode = (int)HttpStatusCode.Forbidden;
res.EndServiceStackRequest(skipHeaders: true);
}
}
}
I've mocked out all the dependencies used by 'othercode()' and all that's left is the stuff that's in the base class Service. Is there a pattern/strategy/approach/something I'm missing that makes this trivial?
Here's how to test with Moq. This service looks for a "key" and "value" in the query string and another parameter in the request DTO. The service returns a string response based on the value given.
[Test]
public void MyTest()
{
var mockRequestContext = new Mock<IRequestContext>();
var mockedHttpRequest = new Mock<IHttpRequest>();
NameValueCollection querystring = new NameValueCollection();
querystring.Add("myKey", "myValue");
mockedHttpRequest.SetupGet(r => r.QueryString).Returns(querystring);
mockRequestContext.Setup(x => x.Get<IHttpRequest>()).Returns(mockedHttpRequest.Object);
AboutService service = new AboutService
{
RequestContext = mockRequestContext.Object,
};
AboutResponse response = (AboutResponse)service.Any(new About
{
Company = "myOtherValue",
});
Assert.AreEqual(0, response.QueryResult);
Assert.AreEqual("validResponse", response.Version);
}
I apologize for not using moq...already had some of this done using RhinoMocks. I think the concept should transfer to moq. This might be a good resource as well as this this.
Anyway, I think the test code below should get you started. Your seam into mocking Request.OriginalRequest is replaceing the Service.RequestContext with a mock object. Then you just have to mock everything beyond that. It's going to be a lot of 'mocking' and if you repeat to yourself 'Are you mocking me' every time you mock a class it's almost enjoyable.
[Test]
public void testsomethign()
{
var mockedRequestContext = MockRepository.GenerateMock<IRequestContext>();
var mockedHttpRequest = MockRepository.GenerateMock<IHttpRequest>();
var mockedOriginalRequest = MockRepository.GenerateMock<HttpRequestBase>();
var mockedOriginalRequestContext = MockRepository.GenerateMock<RequestContext>();
mockedOriginalRequest.Stub(x => x.RequestContext).Return(mockedOriginalRequestContext);
mockedHttpRequest.Stub(x => x.OriginalRequest).Return(mockedOriginalRequest);
mockedRequestContext.Stub(x => x.Get<IHttpRequest>()).Return(mockedHttpRequest);
var service = new ServiceTests()
{
RequestContext = mockedRequestContext
};
service.Delete(new DeleteRequest());
}
Be sure to check out the namespace: ServiceStack.ServiceInterface.Testing.
In there you can find a MockRequestContext that you can use as follows:
var mockContext = new ServiceStack.ServiceInterface.Testing.MockRequestContext();
//do stuff to set it up if desired...
AboutService service = new AboutService
{
RequestContext = mockContext
};

Categories

Resources