单元测试的code 如下:
public void TestPostArticle() { var article = new Article { Title = "Web API Unit Testing", URL = "https://chsakell.com/web-api-unit-testing", Author = "Chris Sakellarios", DateCreated = DateTime.Now, Contents = "Unit testing Web API.." }; var _articlesController = new ArticlesController(_articleService) { Configuration = new HttpConfiguration(), Request = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri("http://localhost/api/articles") } }; var result = _articlesController.PostArticle(article) as CreatedAtRouteNegotiatedContentResult<Article>; Assert.That(result.RouteName, Is.EqualTo("DefaultApi")); Assert.That(result.Content.ID, Is.EqualTo(result.RouteValues["id"])); Assert.That(result.Content.ID, Is.EqualTo(_randomArticles.Max(a => a.ID))); } |
在controller的实例的时候直接传递IArticleService 实例。
public static IArticleService GetIArticleService() { var _article = new Mock<IArticleService>(); _article.Setup(x => x.GetArticles(It.IsAny<string>())).Returns(new Func<string, List<Article>>(name => { if (string.IsNullOrEmpty(name)) { return _randomArticles; } else { return _randomArticles.FindAll(x => x.Title.Contains(name)); } })); _article.Setup(x => x.GetArticle(It.IsAny<int>())).Returns(new Func<int, Article>(id => { return _randomArticles.Find(x => x.ID == id); })); _article.Setup(x => x.GetArticle(It.IsAny<string>())).Returns(new Func<string, Article>(name => { return _randomArticles.Find(x => x.Title == name); })); _article.Setup(r => r.CreateArticle(It.IsAny<Article>())) .Callback(new Action<Article>(newArticle => { newArticle.DateCreated = DateTime.Now; newArticle.ID = _randomArticles.Last().ID + 1; _randomArticles.Add(newArticle); })); _article.Setup(r => r.UpdateArticle(It.IsAny<Article>())) .Callback(new Action<Article>(x => { var oldArticle = _randomArticles.Find(a => a.ID == x.ID); oldArticle.DateEdited = DateTime.Now; oldArticle.URL = x.URL; oldArticle.Title = x.Title; oldArticle.Contents = x.Contents; oldArticle.BlogID = x.BlogID; })); return _article.Object; } |
由于WebApi一般都是用来提供接口的,使用者往往是以发送http请求来获取数据,我们也可以用这种方式来做单元测试:
public void TestPostArticle2() { var article = new Article { Title = "Web API Unit Testing2", URL = "https://chsakell.com/web-api-unit-testing", Author = "Chris Sakellarios", DateCreated = DateTime.Now, Contents = "Unit testing Web API.." }; var address = "http://localhost:9000/"; using (WebApp.Start<Startup>(address)) { HttpClient _client = new HttpClient(); var response = _client.PostAsJsonAsync<Article>(address + "api/articles/", article).Result; var result = response.Content.ReadAsAsync<Article>().Result; Assert.That(result.Title, Is.EqualTo(article.Title)); Assert.That(_randomArticles.Last().Title, Is.EqualTo(article.Title)); } } |
那么我们如何托起这个web 程序,有如何 使用IOC,
这里IOC 用Autofac,其所用包如下:
Install-Package Owin Install-Package Microsoft.AspNet.WebApi.Owin Install-Package Microsoft.Owin.Host.HttpListener Install-Package Microsoft.Owin.Hosting Install-Package Autofac Install-Package Autofac.WebApi2 public class Startup { public void Configuration(IAppBuilder appBuilder) { var config = new HttpConfiguration(); // config.Services.Replace(typeof(IAssembliesResolver), new CustomAssembliesResolver()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); var builder = new ContainerBuilder(); builder.RegisterApiControllers(typeof(ArticlesController).Assembly); var _articleService = Helper.GetIArticleService(); builder.RegisterInstance(_articleService).As<IArticleService>(); IContainer container = builder.Build(); config.DependencyResolver = new AutofacWebApiDependencyResolver(container); appBuilder.UseWebApi(config); } } |