C# 从配置文件以及响应类型读取文件路径时,单元测试web api控制器错误
您好,我正在创建一个web api控制器,它从web.config读取文件的路径,然后使用OpenXMLSDK读取和加载excel文档。我需要编写一个Nunit测试来测试这个控制器的响应 我基本上有两个问题,都是相关的 问题1 由于我的Nunit在类库项目中,它无法从配置设置中读取值,因此会出错。在控制器的测试中如何处理此问题C# 从配置文件以及响应类型读取文件路径时,单元测试web api控制器错误,c#,nunit,asp.net-web-api2,C#,Nunit,Asp.net Web Api2,您好,我正在创建一个web api控制器,它从web.config读取文件的路径,然后使用OpenXMLSDK读取和加载excel文档。我需要编写一个Nunit测试来测试这个控制器的响应 我基本上有两个问题,都是相关的 问题1 由于我的Nunit在类库项目中,它无法从配置设置中读取值,因此会出错。在控制器的测试中如何处理此问题 public class ExcelService : IExcelService { public IEnumerable<CustomerViewMod
public class ExcelService : IExcelService {
public IEnumerable<CustomerViewModel> GetSpreadsheet() {
string relativePath = ConfigurationManager.AppSettings["filePath"];
IEnumerable<CustomerViewModel> customer = (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
return customer;
}
}
在Nunit测试方法中,它在代码的这一行出错
_response = customerController.GetCustomer();
问题2
同一行代码,即_response=customerController.GetCustomer();也会出错,因为它返回类型viewmodel而不是response。如何测试响应对象。或者我需要测试视图模型对象。任何见解都会有帮助
WebApi控制器方法
public IEnumerable<CustomerViewModel> GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
return (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
}
[Test]
public void GetCustomerTest()
{
var customerController = new CustomerController()
{
Request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(ServiceBaseURL + "api/getcustomer")
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
_response = customerController.GetCustomer();
var responseResult = JsonConvert.DeserializeObject<List<CustomerViewModel>>(_response.Content.ReadAsStringAsync().Result);
Assert.AreEqual(_response.StatusCode, HttpStatusCode.OK);
Assert.AreEqual(responseResult.Any(), true);
}
[HttpGet]
public HttpResponseMessage GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
IEnumerable <CustomerViewModel> customerViewModel = (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, customerViewModel);
return response;
}
public IEnumerable GetCustomer()
{
string relativePath=ConfigurationManager.AppSettings[“文件路径”];
返回(OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,relativePath));
}
Nunit测试方法
public IEnumerable<CustomerViewModel> GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
return (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
}
[Test]
public void GetCustomerTest()
{
var customerController = new CustomerController()
{
Request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(ServiceBaseURL + "api/getcustomer")
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
_response = customerController.GetCustomer();
var responseResult = JsonConvert.DeserializeObject<List<CustomerViewModel>>(_response.Content.ReadAsStringAsync().Result);
Assert.AreEqual(_response.StatusCode, HttpStatusCode.OK);
Assert.AreEqual(responseResult.Any(), true);
}
[HttpGet]
public HttpResponseMessage GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
IEnumerable <CustomerViewModel> customerViewModel = (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, customerViewModel);
return response;
}
[测试]
public void GetCustomerTest()
{
var customerController=新customerController()
{
请求=新的HttpRequestMessage
{
Method=HttpMethod.Get,
RequestUri=新Uri(ServiceBaseURL+“api/getcustomer”)
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey,新的HttpConfiguration());
_response=customerController.GetCustomer();
var responseResult=JsonConvert.DeserializeObject(_response.Content.ReadAsStringAsync().Result);
Assert.AreEqual(_response.StatusCode,HttpStatusCode.OK);
Assert.AreEqual(responseResult.Any(),true);
}
根据建议
更新的WebAPI方法
public IEnumerable<CustomerViewModel> GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
return (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
}
[Test]
public void GetCustomerTest()
{
var customerController = new CustomerController()
{
Request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(ServiceBaseURL + "api/getcustomer")
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
_response = customerController.GetCustomer();
var responseResult = JsonConvert.DeserializeObject<List<CustomerViewModel>>(_response.Content.ReadAsStringAsync().Result);
Assert.AreEqual(_response.StatusCode, HttpStatusCode.OK);
Assert.AreEqual(responseResult.Any(), true);
}
[HttpGet]
public HttpResponseMessage GetCustomer()
{
string relativePath = ConfigurationManager.AppSettings["filePath"];
IEnumerable <CustomerViewModel> customerViewModel = (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, customerViewModel);
return response;
}
[HttpGet]
公共HttpResponseMessage GetCustomer()
{
string relativePath=ConfigurationManager.AppSettings[“文件路径”];
IEnumerable CustomerServiceWModel=(OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,relativePath));
HttpResponseMessage response=Request.CreateResponse(HttpStatusCode.OK,CustomServiceWModel);
返回响应;
}
1)更新测试的app.config
文件中的应用程序设置,以匹配web项目的web.config
2) 让操作返回IHttpActionResult
抽象,这将在测试时提供更大的灵活性
public IHttpActionResult GetCustomer(){
string relativePath=ConfigurationManager.AppSettings[“文件路径”];
IEnumerable customer=(OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,relativePath));
返回Ok(客户);
}
您还应该抽象openxml,以允许在单元测试期间模拟文件访问
公共类CustomerController:ApicController{
专用只读IExcelService服务;
公共客户控制器(IExcelService服务){
服务=服务;
}
[HttpGet]
公共IHttpActionResult GetCustomer(){
IEnumerable customer=service.GetSpreadsheet();
返回Ok(客户);
}
}
服务合同可能是这样的
公共接口IExcelService{
IEnumerable GetSpreadsheet();
}
使用一个实现,该实现具有控制器中最初的功能
public class ExcelService : IExcelService {
public IEnumerable<CustomerViewModel> GetSpreadsheet() {
string relativePath = ConfigurationManager.AppSettings["filePath"];
IEnumerable<CustomerViewModel> customer = (OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relativePath)));
return customer;
}
}
公共类ExcelService:IExcelService{
公共IEnumerable GetSpreadsheet(){
string relativePath=ConfigurationManager.AppSettings[“文件路径”];
IEnumerable customer=(OpenSpreadsheetDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,relativePath));
退货客户;
}
}
为了测试,让我们制作一个不依赖于路径的假服务。(注意:这也可以通过模拟框架轻松完成,但出于示例目的,我们将使用一个假框架)
公共类FakeService:IExcelService{
公共IEnumerable GetSpreadsheet(){
返回新列表(){new CustomerViewModel()};
}
}
现在是测试
[Test]
public void GetCustomerTest() {
//Arrange
var fakeService = new FakeService();
var customerController = new CustomerController(fakeService) {
Request = new HttpRequestMessage {
Method = HttpMethod.Get,
RequestUri = new Uri(ServiceBaseURL + "api/getcustomer")
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
//Act
var _response = customerController.GetCustomer() as OkNegotiatedContentResult<IEnumerable<CustomerViewModel>>;
//Assert
Assert.IsNotNull(_response);
var responseResult = _response.Content;
Assert.IsNotNull(responseResult);
Assert.AreEqual(responseResult.Any(), true);
}
[测试]
public void GetCustomerTest(){
//安排
var fakeService=new fakeService();
var customerController=新customerController(fakeService){
请求=新的HttpRequestMessage{
Method=HttpMethod.Get,
RequestUri=新Uri(ServiceBaseURL+“api/getcustomer”)
}
};
customerController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey,新的HttpConfiguration());
//表演
var\u response=customerController.GetCustomer()作为OkNegotiatedContentResult;
//断言
Assert.IsNotNull(_响应);
var responseResult=\u response.Content;
Assert.IsNotNull(responseResult);
Assert.AreEqual(responseResult.Any(),true);
}
1)更新测试的app.config文件中的app设置,以匹配web项目的web.config。2) 让操作返回IHttpActionResult
抽象,这将在测试时提供更大的灵活性。我的angular应用程序调用此web api获取IEnumerable。如果我将其设置为返回IHttpActionResult,我的angular应用程序将如何工作框架根据从ClientForm请求的类型将其序列化您还应抽象openxml以允许在单元测试期间模拟文件访问Hi Nksoki,我已根据您的建议更新了我的控制器以返回Httpresponse。是否正确?我已根据您的建议在TestProject的app.config中添加了相同的appsettings元素。当我调试单元测试时,它会查找测试项目的应用程序根目录的路径并找到它。使用path.combine读取路径的方式不正确。它在应用程序路径b中搜索Appdata