如果没有对应的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. HTML5 Canvas显示本地图片实例1、Canvas预览图片实例1

    1.前台代码: <input id="fileOne" type="file" /> <canvas id="canvasOne&q ...

  2. (转)ASP.NET MVC 学习第一天

    天道酬勤0322   博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅  | 管理 随笔:10 文章:0 评论:9 引用:0 ASP.NET MVC 学习第一天 今天开始第一天学习as ...

  3. n!(n的阶乘)

    我们在这里介绍一些关于n!的性质. 在计数问题中,经常需要用到n!.有必要了解n!在mod p下的一些性质.下面我们假设p是素数,n!=ape(a无法被p整除),并试图求解e和a mod p(把这个东 ...

  4. IDirect3DDevice9::Clear

    在绘制每一帧图形前都要先清空视区,即清空渲染目标表面上的视区矩形的内容:颜色缓冲区.深度缓冲区或者模板缓冲区. HRESULT Clear(  [in]  DWORD Count,           ...

  5. dedecms _ 当前位置问题的代码

    {dede:field name='position' runphp='yes'} $tc=" > "; $tf=split($tc,@me); $tn=count($tf) ...

  6. python中的super

    super用于类的继承.用super()代替父类名 (一)通过类名调用父类中的方法                                                         (二 ...

  7. SQL建模错误--逗号分隔值

    最近帮一个客户分析SQL语句的问题,大致经过如下 场景: 委托方有一个用于追踪他们产品的系统,每个产品都会卖给许多客户:但是客户又被从业务上分成两类,一类是带有合作伙伴性质的,这个 合作伙伴通常会给予 ...

  8. gtest以及测试小结

    所有的测试,都是让未知的东西和已知的东西进行比较,如果测试结果和预期的一样,那么就认为被测对象是OK的否则视为有问题. python的单元测试是写一堆继承了unittest.TestCase类,每个类 ...

  9. Linux & Python 导航目录

    < Python学习手册(第4版)>< Python Cookbook(第2版)>中文版.pdf< Python 高级编程>< Python 基础教程 第二版 ...

  10. linux虚拟机命令行模式下,某些命令显示乱码问题。

    刚安装了linux虚拟机,使用vi命令试着修改IP配置,结果出现乱码.配置IP的文件内容本身没有乱码,主要是vi编辑的命令行的提示出现乱码,例如,按i是插入模式,结果底下出现乱码提升,不是提示插入. ...