我试图找到如何模拟MVC / Web Api控制器内可用的请求和响应对象.
这是可能的,我没有注入Request和Response对象,这些是可用的,因为控制器继承自ApiController或Controller.
有没有人有一些很好的例子来通过nsubstitute访问这些?
还有像上下文这样的其他对象呢?
解决方法
你不必嘲笑它们.
由于它们具有读/写属性,因此您只需创建它们即可.我在book中解释了一下,我们有一个允许你这样做的课程:
var orderController = ControllerContextSetup .Of(() => new OrderController(mockOrderService.Object)) .WithDefaultConfig() .WithDefaultRoute() .Requesting(url) .WithRouteData(new {controller="Order"}) .Build<OrderController>();
public class ControllerContextSetup { private const string DefaultApiName = "DefaultApi"; private readonly ApiController _controller; private HttpRouteData _httpRouteData; private ControllerContextSetup(ApiController controller) { _controller = controller; _controller.Request = new HttpRequestMessage(); } public static ControllerContextSetup Of<T>(Func<T> factory) where T : ApiController { return new ControllerContextSetup(factory()); } public static ControllerContextSetup Of<T>() where T : ApiController,new() { return new ControllerContextSetup(new T()); } public ControllerContextSetup WithDefaultConfig() { _controller.Configuration = new HttpConfiguration(); _controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = _controller.Configuration; return this; } public ControllerContextSetup WithConfig(HttpConfiguration configuration) { _controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration; _controller.Configuration = configuration; return this; } public ControllerContextSetup Requesting(string uriString) { Uri uri = null; bool success = Uri.TryCreate(uriString,UriKind.Relative,out uri); if (success) return Requesting(uri); success = Uri.TryCreate(uriString,UriKind.Absolute,out uri); if(success) return Requesting(uri); return Requesting(new Uri(uriString)); } public ControllerContextSetup Requesting(Uri uri) { _controller.Request.RequestUri = uri; return this; } public ControllerContextSetup WithDefaultRoute() { _controller.Configuration.Routes.MapHttpRoute( name: DefaultApiName,routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional } ); return this; } public ControllerContextSetup WithRoute(string name,string routeTemplate) { _controller.Configuration.Routes.MapHttpRoute(name,routeTemplate); return this; } public ControllerContextSetup WithRoute(string name,string routeTemplate,object defaults) { _controller.Configuration.Routes.MapHttpRoute(name,routeTemplate,defaults); return this; } public ControllerContextSetup WithRoute(string name,object defaults,object constraints) { _controller.Configuration.Routes.MapHttpRoute(name,defaults,constraints); return this; } public ControllerContextSetup WithRoute(string name,IHttpRoute route) { _controller.Configuration.Routes.Add(name,route); return this; } /// <summary> /// Uses default route /// </summary> /// <param name="routeValues"></param> /// <returns></returns> public ControllerContextSetup WithRouteData(object routeValues) { return WithRouteData(new HttpRouteValueDictionary(routeValues)); } /// <summary> /// Uses default route /// </summary> /// <param name="routeValues"></param> /// <returns></returns> public ControllerContextSetup WithRouteData(HttpRouteValueDictionary routeValues) { var route = _controller.Configuration.Routes[DefaultApiName]; _httpRouteData = new HttpRouteData(route,routeValues); _controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = _httpRouteData; return this; } public ControllerContextSetup WithMethod(HttpMethod method) { _controller.Request.Method = method; return this; } public ApiController Build() { _controller.ControllerContext = new HttpControllerContext(_controller.Configuration,_httpRouteData ?? new HttpRouteData(_controller.Configuration.Routes.FirstOrDefault()),_controller.Request); return _controller; } public T Build<T>() where T : ApiController { return (T) Build(); } }