大佬教程收集整理的这篇文章主要介绍了c# – 单元测试上载文件的Web API端点,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
对于单元测试,我使用:Xunit,Moq和Fluent Assertions
下面是我的控制器与端点:
public class MyAppController : ApiController { private readonly IMyApp _myApp; public MyAppController(IMyApp myApp) { if (myApp == null) throw new ArgumentNullException(nameof(myApp)); _myApp = myApp; } [HttpPost] [ResponseType(typeof(string))] [Route("api/myApp/UploadFile")] [SwaggerUploadFile("myFile","Upload a .zip format file",required = true,Type = "file")] public async Task<IHttpActionResult> UploadFile() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } var provider = await Request.Content.ReadAsMultipartAsync(); var bytes = await provider.Contents.First().ReadAsByteArrayAsync(); try { var retVal = _myApp.CheckAndSaveByteStreamAsync(bytes).Result; if(retVal) { return ResponseMessage( new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonConvert.SerializeObject( new WebApiResponse { Message = "File has been saved" }),Encoding.UTF8,"application/json") }); } return ResponseMessage( new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(JsonConvert.SerializeObject( new WebApiResponse { Message = "The file Could not be saved" }),"application/json") }); } catch (Exception e) { //log error return BadRequest("Oops...something went wrong"); } } }
我到目前为止的单元测试:
[Fact] [Trait("Category","MyAppController")] public void UploadFileTestWorks() { //Arrange _myApp.Setup(x => x.CheckAndSaveByteStreamAsync(It.IsAny<byte[]>())).ReturnsAsync(() => true); var expected = JsonConvert.SerializeObject( new WebApiResponse { Message = "The file has been saved" }); var _sut = new MyAppController(_myApp.Object); //Act var retVal = _sut.UploadFile(); var content = (ResponseMessageResult)retVal.Result; var contentResult = content.Response.Content.ReadAsStringAsync().Result; //Assert contentResult.Should().Be(expected); }
如果(!Request.Content.IsMimeMultipartContent())我们得到NullReferenceException> “{“你调用的对象是空的.”}”
最佳答案已实施:
创建了一个界面:
public interface IApiRequestProvider { Task<MultipartMemoryStreamProvider> ReadAsMultiPartAsync(); bool IsMimeMultiPartContent(); }
然后是一个实现:
public class ApiRequestProvider : ApiController,IApiRequestProvider { public Task<MultipartMemoryStreamProvider> ReadAsMultiPartAsync() { return Request.Content.ReadAsMultipartAsync(); } public bool IsMimeMultiPartContent() { return Request.Content.IsMimeMultipartContent(); } }
现在我的控制器使用构造函数注入来获取RequestProvider:
private readonly IMyApp _myApp; private readonly IApiRequestProvider _apiRequestProvider; public MyAppController(IMyApp myApp,IApiRequestProvider apiRequestProvider) { if (myApp == null) throw new ArgumentNullException(nameof(myApp)); _myApp = myApp; if (apiRequestProvider== null) throw new ArgumentNullException(nameof(apiRequestProvider)); _apiRequestProvider= apiRequestProvider; }
方法的新实现:
[HttpPost] [ResponseType(typeof(string))] [Route("api/myApp/UploadFile")] [SwaggerUploadFile("myFile",Type = "file")] public async Task<IHttpActionResult> UploadFile() { if (!_apiRequestProvider.IsMimeMultiPartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } var provider = await _apiRequestProvider.ReadAsMultiPartAsync(); var bytes = await provider.Contents.First().ReadAsByteArrayAsync(); try { var retVal = _myApp.CheckAndSaveByteStreamAsync(bytes).Result; if(retVal) { return ResponseMessage( new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonConvert.SerializeObject( new WebApiResponse { Message = "File has been saved" }),"application/json") }); } catch (Exception e) { //log error return BadRequest("Oops...something went wrong"); } } }
我的单元测试嘲笑ApiController请求:
[Fact] [Trait("Category","MyAppController")] public void UploadFileTestWorks() { //Arrange _apiRequestProvider = new Mock<IApiRequestProvider>(); _myApp = new Mock<IMyApp>(); MultipartMemoryStreamProvider fakeStream = new MultipartMemoryStreamProvider(); fakeStream.Contents.Add(CreateFakeMultiPartFormData()); _apiRequestProvider.Setup(x => x.IsMimeMultiPartContent()).Returns(true); _apiRequestProvider.Setup(x => x.ReadAsMultiPartAsync()).ReturnsAsync(()=>fakeStream); _myApp.Setup(x => x.CheckAndSaveByteStreamAsync(It.IsAny<byte[]>())).ReturnsAsync(() => true); var expected = JsonConvert.SerializeObject( new WebApiResponse { Message = "The file has been saved" }); var _sut = new MyAppController(_myApp.Object,_apiRequestProvider.Object); //Act var retVal = _sut.UploadFile(); var content = (ResponseMessageResult)retVal.Result; var contentResult = content.Response.Content.ReadAsStringAsync().Result; //Assert contentResult.Should().Be(expected); }
感谢@Badulake的想法
var provider = await Request.Content.ReadAsMultipartAsync();
可以转换为:
var provider = IProviderExtracter.Extract(); public interface IProviderExtracter { Task<provider> Extract(); } public class RequestProviderExtracter:IProviderExtracter { public Task<provider> Extract() { return Request.Content.ReadAsMultipartAsync(); } }
在您的测试中,您可以轻松地模拟IProviderExtracter,并专注于执行代码的每个部分.
我们的想法是获得最多的解耦代码,因此您的担忧只集中在模拟您开发的类,而不是框架强制您使用的类.
以上是大佬教程为你收集整理的c# – 单元测试上载文件的Web API端点全部内容,希望文章能够帮你解决c# – 单元测试上载文件的Web API端点所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。