如果没有对应的web api模板,首先使用nuget进行安装

例子1:

ProductController 是以硬编码的方式使用StoreAppContext类的实例,可以使用依赖注入模式,在外部指定上下文实例

  public interface IStoreAppContext:IDisposable
{
DbSet<Product> Products { get; set; }
int SaveChanges();
void MarkAsModified(Product item);
} public class StoreAppContext : DbContext,IStoreAppContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx public StoreAppContext() : base("name=StoreAppContext")
{
} public DbSet<Product> Products { get; set; } public void MarkAsModified(Product item)
{
Entry(item).State = EntityState.Modified;
}
} public class ProductsController : ApiController
{
private IStoreAppContext db = new StoreAppContext(); public ProductsController() { } public ProductsController(IStoreAppContext context)
{
db = context;
}
// GET: api/Products
public IQueryable<Product> GetProducts()
{
return db.Products;
} // GET: api/Products/5
[ResponseType(typeof(Product))]
public IHttpActionResult GetProduct(int id)
{
Product product = db.Products.Find(id);
if (product == null)
{
return NotFound();
} return Ok(product);
} // PUT: api/Products/5
[ResponseType(typeof(void))]
public IHttpActionResult PutProduct(int id, Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} if (id != product.Id)
{
return BadRequest();
} db.MarkAsModified(product); try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(id))
{
return NotFound();
}
else
{
throw;
}
} return StatusCode(HttpStatusCode.NoContent);
} // POST: api/Products
[ResponseType(typeof(Product))]
public IHttpActionResult PostProduct(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} db.Products.Add(product);
db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = product.Id }, product);
} // DELETE: api/Products/5
[ResponseType(typeof(Product))]
public IHttpActionResult DeleteProduct(int id)
{
Product product = db.Products.Find(id);
if (product == null)
{
return NotFound();
} db.Products.Remove(product);
db.SaveChanges(); return Ok(product);
} protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
} private bool ProductExists(int id)
{
return db.Products.Count(e => e.Id == id) > ;
}
}

单元测试代码:

  public  class TestDbSet<T>:DbSet<T>,IQueryable,IEnumerable<T>
where T:class
{
ObservableCollection<T> _data;
IQueryable _query; public TestDbSet()
{
_data = new ObservableCollection<T>();
_query = _data.AsQueryable();
} public override T Add(T item)
{
_data.Add(item);
return item;
} public override T Remove(T item)
{
_data.Remove(item);
return item;
} public override T Attach(T item)
{
_data.Add(item);
return item;
} public override T Create()
{
return Activator.CreateInstance<T>();
} public override TDerivedEntity Create<TDerivedEntity>()
{
return Activator.CreateInstance<TDerivedEntity>();
} public override ObservableCollection<T> Local
{
get { return new ObservableCollection<T>(_data); }
} Type IQueryable.ElementType
{
get { return _query.ElementType; }
} System.Linq.Expressions.Expression IQueryable.Expression
{
get { return _query.Expression; }
} IQueryProvider IQueryable.Provider
{
get { return _query.Provider; }
} System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
} IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
} class TestProductDbSet:TestDbSet<Product>
{
public override Product Find(params object[] keyValues)
{
return this.SingleOrDefault(p=>p.Id==(int)keyValues.Single());
}
} class TestStoreAppContext : IStoreAppContext
{
public TestStoreAppContext()
{
this.Products = new TestProductDbSet();
} public System.Data.Entity.DbSet<Product> Products { get; set; } public int SaveChanges()
{
return ;
} public void MarkAsModified(Product item)
{ } public void Dispose()
{ }
} public class TestProductController
{
[TestMethod]
public void PostProduct_ShouldReturnSameProduct()
{
var controller = new ProductsController(new TestStoreAppContext());
var item = GetDemoProduct(); var result=controller.PostProduct(item) as CreatedAtRouteNegotiatedContentResult<Product>;
Assert.IsNotNull(result);
Assert.AreEqual(result.RouteName, "DefaultApi");
Assert.AreEqual(result.RouteValues["id"], result.Content.Id);
Assert.AreEqual(result.Content.Name, item.Name);
}
[TestMethod]
public void PutProduct_ShouldReturnStatusCode()
{
var controller = new ProductsController(new TestStoreAppContext()); var item = GetDemoProduct(); var result = controller.PutProduct(item.Id, item) as StatusCodeResult;
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result, typeof(StatusCodeResult));
Assert.AreEqual(HttpStatusCode.NoContent, result.StatusCode);
} [TestMethod]
public void PutProduct_ShouldFail_WhenDifferentID()
{
var controller = new ProductsController(new TestStoreAppContext()); var badresult = controller.PutProduct(, GetDemoProduct());
Assert.IsInstanceOfType(badresult, typeof(BadRequestResult));
} [TestMethod]
public void GetProduct_ShouldReturnProductWithSameID()
{
var context = new TestStoreAppContext();
context.Products.Add(GetDemoProduct()); var controller = new ProductsController(context);
var result = controller.GetProduct() as OkNegotiatedContentResult<Product>; Assert.IsNotNull(result);
Assert.AreEqual(, result.Content.Id);
} [TestMethod]
public void GetProducts_ShouldReturnAllProducts()
{
var context = new TestStoreAppContext();
context.Products.Add(new Product { Id = , Name = "Demo1", Price = });
context.Products.Add(new Product { Id = , Name = "Demo2", Price = });
context.Products.Add(new Product { Id = , Name = "Demo3", Price = }); var controller = new ProductsController(context);
var result = controller.GetProducts() as TestProductDbSet; Assert.IsNotNull(result);
Assert.AreEqual(, result.Local.Count);
} [TestMethod]
public void DeleteProduct_ShouldReturnOK()
{
var context = new TestStoreAppContext();
var item = GetDemoProduct();
context.Products.Add(item); var controller = new ProductsController(context);
var result = controller.DeleteProduct() as OkNegotiatedContentResult<Product>; Assert.IsNotNull(result);
Assert.AreEqual(item.Id, result.Content.Id);
}
Product GetDemoProduct()
{
return new Product() { Id = , Name = "Demo name", Price = };
}
}

具体的代码参见:Mocking Entity Framework when Unit Testing ASP.NET Web API 2

WebApi2官网学习记录---单元测试的更多相关文章

  1. WebApi2官网学习记录---Cookie

    Cookie的几个参数: Domain.Path.Expires.Max-Age 如果Expires与Max-Age都存在,Max-Age优先级高,如果都没有设置cookie会在会话结束后删除cook ...

  2. WebApi2官网学习记录---批量处理HTTP Message

    原文:Batching Handler for ASP.NET Web API 自定义实现HttpMessageHandler public class BatchHandler : HttpMess ...

  3. WebApi2官网学习记录---Html Form Data

    HTML Forms概述 <form action="api/values" method="post"> 默认的method是GET,如果使用GE ...

  4. WebApi2官网学习记录--HttpClient Message Handlers

    在客户端,HttpClient使用message handle处理request.默认的handler是HttpClientHandler,用来发送请求和获取response从服务端.可以在clien ...

  5. WebApi2官网学习记录--HTTP Message Handlers

    Message Handlers是一个接收HTTP Request返回HTTP Response的类,继承自HttpMessageHandler 通常,一些列的message handler被链接到一 ...

  6. WebApi2官网学习记录---Configuring

    Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...

  7. WebApi2官网学习记录--- Authentication与Authorization

    Authentication(认证)   WebAPI中的认证既可以使用HttpModel也可以使用HTTP message handler,具体使用哪个可以参考一下依据: 一个HttpModel可以 ...

  8. WebApi2官网学习记录---Tracing

    安装追踪用的包 Install-Package Microsoft.AspNet.WebApi.Tracing Update-Package Microsoft.AspNet.WebApi.WebHo ...

  9. WebApi2官网学习记录---异常处理

    HttpResponseException 当WebAPI的控制器抛出一个未捕获的异常时,默认情况下,大多数异常被转为status code为500的http response即服务端错误. Http ...

随机推荐

  1. Oracle 11g XML java连接

    在网上找了好多教程 走好好多弯路 现在从头总结下 oralce11g 可以直接用xmltype节点存储xml文件 简单来说就是直接存一个文件进去 首先安装oracle11g 网上教程非常多 然后进Ne ...

  2. UI基础视图----UIView总结

    UIView是UIKit框架里面最基础的视图类,是UIResponder的子类,是UIApplication和UIViewController的兄弟类,是UIWindow,UILabel,UIImag ...

  3. [c#]控制台进度条的示例

    看到[vb.net]控制台进度条的示例 感觉很好玩,翻译成C#版. using System; using System.Collections.Generic; using System.Linq; ...

  4. (原创) jetson tk1 初始化

    1. 相关的网站: 1. Jetson TK1 support   https://developer.nvidia.com/jetson-tk1-support 2.official Wiki fo ...

  5. dede后台反应特别慢-转

    找到织梦后台管理目录下的/templets/index_body.htm文件 将第25行至第35行部分js代码注释掉. 就这么简单

  6. IE,火狐,谷歌浏览器下js判断滚动条是否已拉到页面最底部

    E/FF/Chrome下document.documentElement和document.body的 scrollHeight/scrollTop/clientHeight 以及判断滚动条是否已拉到 ...

  7. 关于mobiscroll插件的使用

    在网上找了很多资料,各大猿友对这个插件都做了很详细的介绍,我也是看了很多资料才发现原来这个插件有一些需要注意的地方,在这总结了一下: //时间 var currYear = (new Date()). ...

  8. IOS 播放音频流媒体

    #pragma mark - 加载播放数据 - (void)loadData:(NSString *)musicUrl { NSURL *playURL = [NSURL URLWithString: ...

  9. Caffe : Layer Catalogue(2)

    TanH / Hyperbolic Tangent 类型(type):TanH CPU 实现: ./src/caffe/layers/tanh_layer.cpp CUDA.GPU实现: ./src/ ...

  10. composer在ubuntu下安装

    通过curl下载composer安装包 curl -sS https://getcomposer.org/installer | php 将安装包移动到全局安装文件夹下 mv composer.pha ...