public async Task <TwilioResponse> DoApiCall(string url, TwilioRequest request, bool redirects = true) { HttpRequestMessage requestMessage; HttpControllerContext ctrlContext; MethodInfo method; GetActionMethod(url, out requestMessage, out ctrlContext, out method); var controller = new VoiceController(() => this.DBMock.Object, this.EventsServiceMock.Object, this.ConfigMock.Object, this.MembersMock.Object, new ConsoleLogger()); controller.ControllerContext = ctrlContext; controller.RequestContext.Url = new System.Web.Http.Routing.UrlHelper(requestMessage); var queryArgs = ctrlContext.Request.GetQueryNameValuePairs().ToDictionary(f => f.Key, f => f.Value); controller.InitBody(queryArgs); var parameters = method.GetParameters(); List <object> arguments = new List <object>(); foreach (var parameter in parameters) { if (parameter.ParameterType == typeof(TwilioRequest)) { arguments.Add(request); } else if (parameter.ParameterType == typeof(string)) { arguments.Add(queryArgs[parameter.Name]); } else { throw new NotImplementedException("Don't know how to bind parameter " + parameter.Name + " with type " + parameter.ParameterType.Name); } } TwilioResponse result; if (method.ReturnType == typeof(TwilioResponse)) { result = (TwilioResponse)method.Invoke(controller, arguments.ToArray()); } else if (method.ReturnType == typeof(Task <TwilioResponse>)) { result = await(Task <TwilioResponse>) method.Invoke(controller, arguments.ToArray()); } else { throw new NotImplementedException("API controller returns type " + method.ReturnType.Name); } var first = result.ToXDocument().Root.FirstNode as XElement; if (redirects && first != null && first.Name == "Redirect") { result = await DoApiCall(first.Value, CreateRequest(null), true); } return(result); }