如何在Web API中模拟Request.form
问题描述:
我想为我的ApiController编写一些单元测试并遇到一些问题。如何在Web API中模拟Request.form
这里是我的TestMethod的
[TestMethod]
public void CustomerController_AddUnitTest()
{
var custid = Guid.NewGuid();
var customers = new Customer() { CustomerName = "Enterprise", CustomerId = custid };
var rmContext = MockRepository.GenerateMock<HttpContextBase>();
var rmRequest = MockRepository.GenerateMock<HttpRequestBase>();
rmContext.Stub(x => x.Request).Return(rmRequest);
var FormData = new NameValueCollection { { "FirstName", "Jonathan" }, { "LastName", "Danylko" } };
rmRequest.Stub(r => r.Form).Return(FormData);
rmContext.Stub(p => p.Request).Return(rmRequest);
var forms = rmContext.Request.Form;
> // here i am able to get forms value but i couldn't pass these value
> to main controller
var mockRepository = MockRepository.GenerateMock<ICustomerService>();
mockRepository.Stub(x => x.Add(new Customer())).IgnoreArguments().Return(1);
_customerController = new CustomerController(mockRepository);
var result = _customerController.CustomerAdd();
Assert.IsNotNull(result);
}
这是我的控制器代码看起来像
public int CustomerAdd()
{
var localhost = HttpContext.Current.Request.Url.Authority;
var formData = HttpContext.Current.Request.Form["FormData"];
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
var customer = json_serializer.Deserialize<Customer>(formData);
if (HttpContext.Current.Request.Files.Count > 0)
{
HttpPostedFile file = HttpContext.Current.Request.Files[0];
string fileName = customer.CustomerName.Trim() + "_" + file.FileName;
var filePath = HttpContext.Current.Server.MapPath(Constants.FileUploadImagePath + fileName);
file.SaveAs(filePath);
customer.Logo = fileName;
}
return _iCustomerService.Add(customer);
}
我想模拟数据传递给var formData = HttpContext.Current.Request.Form["FormData"];
任何人都可以有一个想法来解决这个问题我真的厌倦了这个任务。
答
将线拉出到一个单独的(虚拟)方法中,然后在测试中,使用控制器的部分模拟器,在该模拟器中存入新方法以返回模拟数据。 (这被称为“测试缝”FYI)。
事情是这样的:
public int CustomerAdd()
{
var localhost = HttpContext.Current.Request.Url.Authority;
var formData = GetFormData()["FormData"];
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
var customer = json_serializer.Deserialize<Customer>(formData);
if (HttpContext.Current.Request.Files.Count > 0)
{
HttpPostedFile file = HttpContext.Current.Request.Files[0];
string fileName = customer.CustomerName.Trim() + "_" + file.FileName;
var filePath = HttpContext.Current.Server.MapPath(Constants.FileUploadImagePath + fileName);
file.SaveAs(filePath);
customer.Logo = fileName;
}
return _iCustomerService.Add(customer);
}
public virtual NameValueCollection GetFormDatat()
{
return HttpContext.Current.Request.Form;
}
然后在您的测试使用:
_customerController = MockRepository.GeneratePartialMock<CustomerContoller>();
_customerController.Stub(c => c.GetFormData()).Return(yourFakeFormData);
或者,你可以做同样的事情,但对于上下文对象的用法。
+0
作为一般说明,您绝不希望生产代码直接引用您的模拟框架类型。在原始文章中,您将显示控制器类将模拟存储库作为构造参数 - 这绝不应该发生。模拟框架旨在模拟您实际使用的类型,因此您的产品无需了解您的测试代码。 –
被测方法设计不佳,与静态依赖性紧密相关,这使得测试变得困难。尽量避免将你的代码紧密耦合到'HttpContext'。 – Nkosi
是的,我知道。但我不知道如何模拟这一行代码 –
var formData = HttpContext.Current.Request.Form [“FormData”]; –