如果没有对应的web api模板,首先使用nuget进行安装
例子1:
ProductController 是以硬编码的方式使用StoreAppContext类的实例,可以使用依赖注入模式,在外部指定上下文实例
1 public interface IStoreAppContext:IDisposable 2 { 3 DbSetProducts { get; set; } 4 int SaveChanges(); 5 void MarkAsModified(Product item); 6 } 7 8 public class StoreAppContext : DbContext,IStoreAppContext 9 { 10 // You can add custom code to this file. Changes will not be overwritten. 11 // 12 // If you want Entity Framework to drop and regenerate your database 13 // automatically whenever you change your model schema, please use data migrations. 14 // For more information refer to the documentation: 15 // http://msdn.microsoft.com/en-us/data/jj591621.aspx 16 17 public StoreAppContext() : base("name=StoreAppContext") 18 { 19 } 20 21 public DbSet Products { get; set; } 22 23 public void MarkAsModified(Product item) 24 { 25 Entry(item).State = EntityState.Modified; 26 } 27 } 28 29 public class ProductsController : ApiController 30 { 31 private IStoreAppContext db = new StoreAppContext(); 32 33 public ProductsController() { } 34 35 public ProductsController(IStoreAppContext context) 36 { 37 db = context; 38 } 39 // GET: api/Products 40 public IQueryable GetProducts() 41 { 42 return db.Products; 43 } 44 45 // GET: api/Products/5 46 [ResponseType(typeof(Product))] 47 public IHttpActionResult GetProduct(int id) 48 { 49 Product product = db.Products.Find(id); 50 if (product == null) 51 { 52 return NotFound(); 53 } 54 55 return Ok(product); 56 } 57 58 // PUT: api/Products/5 59 [ResponseType(typeof(void))] 60 public IHttpActionResult PutProduct(int id, Product product) 61 { 62 if (!ModelState.IsValid) 63 { 64 return BadRequest(ModelState); 65 } 66 67 if (id != product.Id) 68 { 69 return BadRequest(); 70 } 71 72 db.MarkAsModified(product); 73 74 try 75 { 76 db.SaveChanges(); 77 } 78 catch (DbUpdateConcurrencyException) 79 { 80 if (!ProductExists(id)) 81 { 82 return NotFound(); 83 } 84 else 85 { 86 throw; 87 } 88 } 89 90 return StatusCode(HttpStatusCode.NoContent); 91 } 92 93 // POST: api/Products 94 [ResponseType(typeof(Product))] 95 public IHttpActionResult PostProduct(Product product) 96 { 97 if (!ModelState.IsValid) 98 { 99 return BadRequest(ModelState);100 }101 102 db.Products.Add(product);103 db.SaveChanges();104 105 return CreatedAtRoute("DefaultApi", new { id = product.Id }, product);106 }107 108 // DELETE: api/Products/5109 [ResponseType(typeof(Product))]110 public IHttpActionResult DeleteProduct(int id)111 {112 Product product = db.Products.Find(id);113 if (product == null)114 {115 return NotFound();116 }117 118 db.Products.Remove(product);119 db.SaveChanges();120 121 return Ok(product);122 }123 124 protected override void Dispose(bool disposing)125 {126 if (disposing)127 {128 db.Dispose();129 }130 base.Dispose(disposing);131 }132 133 private bool ProductExists(int id)134 {135 return db.Products.Count(e => e.Id == id) > 0;136 }137 }
单元测试代码:
1 public class TestDbSet:DbSet ,IQueryable,IEnumerable 2 where T:class 3 { 4 ObservableCollection _data; 5 IQueryable _query; 6 7 public TestDbSet() 8 { 9 _data = new ObservableCollection (); 10 _query = _data.AsQueryable(); 11 } 12 13 public override T Add(T item) 14 { 15 _data.Add(item); 16 return item; 17 } 18 19 public override T Remove(T item) 20 { 21 _data.Remove(item); 22 return item; 23 } 24 25 public override T Attach(T item) 26 { 27 _data.Add(item); 28 return item; 29 } 30 31 public override T Create() 32 { 33 return Activator.CreateInstance (); 34 } 35 36 public override TDerivedEntity Create () 37 { 38 return Activator.CreateInstance (); 39 } 40 41 public override ObservableCollection Local 42 { 43 get { return new ObservableCollection (_data); } 44 } 45 46 Type IQueryable.ElementType 47 { 48 get { return _query.ElementType; } 49 } 50 51 System.Linq.Expressions.Expression IQueryable.Expression 52 { 53 get { return _query.Expression; } 54 } 55 56 IQueryProvider IQueryable.Provider 57 { 58 get { return _query.Provider; } 59 } 60 61 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 62 { 63 return _data.GetEnumerator(); 64 } 65 66 IEnumerator IEnumerable .GetEnumerator() 67 { 68 return _data.GetEnumerator(); 69 } 70 } 71 72 class TestProductDbSet:TestDbSet 73 { 74 public override Product Find(params object[] keyValues) 75 { 76 return this.SingleOrDefault(p=>p.Id==(int)keyValues.Single()); 77 } 78 } 79 80 class TestStoreAppContext : IStoreAppContext 81 { 82 public TestStoreAppContext() 83 { 84 this.Products = new TestProductDbSet(); 85 } 86 87 public System.Data.Entity.DbSet Products { get; set; } 88 89 90 public int SaveChanges() 91 { 92 return 0; 93 } 94 95 public void MarkAsModified(Product item) 96 { 97 98 } 99 100 public void Dispose()101 {102 103 }104 }105 106 public class TestProductController107 {108 [TestMethod]109 public void PostProduct_ShouldReturnSameProduct()110 {111 var controller = new ProductsController(new TestStoreAppContext());112 var item = GetDemoProduct();113 114 var result=controller.PostProduct(item) as CreatedAtRouteNegotiatedContentResult ;115 Assert.IsNotNull(result);116 Assert.AreEqual(result.RouteName, "DefaultApi");117 Assert.AreEqual(result.RouteValues["id"], result.Content.Id);118 Assert.AreEqual(result.Content.Name, item.Name);119 }120 [TestMethod]121 public void PutProduct_ShouldReturnStatusCode()122 {123 var controller = new ProductsController(new TestStoreAppContext());124 125 var item = GetDemoProduct();126 127 var result = controller.PutProduct(item.Id, item) as StatusCodeResult;128 Assert.IsNotNull(result);129 Assert.IsInstanceOfType(result, typeof(StatusCodeResult));130 Assert.AreEqual(HttpStatusCode.NoContent, result.StatusCode);131 }132 133 [TestMethod]134 public void PutProduct_ShouldFail_WhenDifferentID()135 {136 var controller = new ProductsController(new TestStoreAppContext());137 138 var badresult = controller.PutProduct(999, GetDemoProduct());139 Assert.IsInstanceOfType(badresult, typeof(BadRequestResult));140 }141 142 [TestMethod]143 public void GetProduct_ShouldReturnProductWithSameID()144 {145 var context = new TestStoreAppContext();146 context.Products.Add(GetDemoProduct());147 148 var controller = new ProductsController(context);149 var result = controller.GetProduct(3) as OkNegotiatedContentResult ;150 151 Assert.IsNotNull(result);152 Assert.AreEqual(3, result.Content.Id);153 }154 155 [TestMethod]156 public void GetProducts_ShouldReturnAllProducts()157 {158 var context = new TestStoreAppContext();159 context.Products.Add(new Product { Id = 1, Name = "Demo1", Price = 20 });160 context.Products.Add(new Product { Id = 2, Name = "Demo2", Price = 30 });161 context.Products.Add(new Product { Id = 3, Name = "Demo3", Price = 40 });162 163 var controller = new ProductsController(context);164 var result = controller.GetProducts() as TestProductDbSet;165 166 Assert.IsNotNull(result);167 Assert.AreEqual(3, result.Local.Count);168 }169 170 [TestMethod]171 public void DeleteProduct_ShouldReturnOK()172 {173 var context = new TestStoreAppContext();174 var item = GetDemoProduct();175 context.Products.Add(item);176 177 var controller = new ProductsController(context);178 var result = controller.DeleteProduct(3) as OkNegotiatedContentResult ;179 180 Assert.IsNotNull(result);181 Assert.AreEqual(item.Id, result.Content.Id);182 }183 Product GetDemoProduct()184 {185 return new Product() { Id = 3, Name = "Demo name", Price = 5 };186 }187 }
具体的代码参见: