We have an azure functions project and it looks like the previous dev used a similar approach as described here for unit testing: http://dontcodetired.com/blog/post/Mocking-HttpRequest-Body-Content-When-Testing-Azure-Function-HTTP-Trigger-Functions
It works well, except that I now need to inject a fake value for the the following string:
HttpContext.Items["MS_AzureFunctionsRequestID"]
cus at some point in the code, we do this:
req.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString()
And right now, the unit test is failing because the fake request object doesn't include this field.
I've tried a few different things but so far, no dice.
Assuming I'm using the following code, where can I inject this fake string:
private static Mock<HttpRequest> CreateMockRequest(object body)
{
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
var json = JsonConvert.SerializeObject(body);
sw.Write(json);
sw.Flush();
ms.Position = 0;
var mockRequest = new Mock<HttpRequest>();
mockRequest.Setup(x => x.Body).Returns(ms);
return mockRequest;
}
I've tried to add an additional "sw.Write()" line and play around with the contents but I can't seem to get it working.
Thanks.
EDIT 1
So I changed the above method so it has one additional line:
private static Mock<HttpRequest> CreateMockRequest(object body)
{
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
var json = JsonConvert.SerializeObject(body);
sw.Write(json);
sw.Flush();
ms.Position = 0;
var mockRequest = new Mock<HttpRequest>();
mockRequest.Setup(x => x.Body).Returns(ms);
mockRequest.Setup(x =>x.HttpContext.Items.Add("MS_AzureFunctionsRequestID", REQID));
return mockRequest;
}
REQID is a new private const that has been defined in the same class as the CreateMockRequest() method.
This is the method that ultimately calls this code:
[Fact]
public async void post_request_should_be_stored_in_queue_and_storage_table(){
var messageQueue = TestFactory.CreateAzureStorageQueue();
var request = TestFactory.CreateWidgetHTTPRequest();
Console.Write(request.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString());
var storageTable = TestFactory.SaveToStorageTable();
var widgetRequest = new WidgetRequest(storageTable);
var response = (OkObjectResult)await widgetRequest.CreateWidget(request, messageQueue, logger);
Assert.NotNull(response);
Assert.True(((AzureStorageQueueTestClient<string>)messageQueue).Messages.Count > 0);
}
When it hits the console.write - the field is null.
Can I call setup on the mock object twice?
how do I set x.body and x.HttpContext?
EDIT 2
I found this post: How to mock HttpContext.Current.Items with NUnit and Rhino Mocks
I'm trying to use the answer to adapt my code, but when I try to create the httpContext object, i'm getting a CS0144 error
"Cannot create an instance of the abstract type or interface 'HttpContext' "Cannot create an instance of the abstract type or interface 'HttpResponse'
The code I'm playing around with so far just has this:
[Fact]
public void can_create_http_context()
{
const string REQUEST_GUID_FIELD_NAME = "RequestGUID";
var httpContext = new HttpContext(new HttpRequest("", "http://google.com", ""), new HttpResponse(new StringWriter()));
HttpContext.Current = httpContext;
}