学习单元测试(一)简单业务中的单元测试
定义领域模型
业务是描述拍卖物品的场景。一组拍卖人,每个拍卖人都有一组报价。每个报价都针对一个物品,而每个物品可以有不同拍卖人的多个报价。
//拍卖 成员类 public class Member { public string LoginName { get; set; }//人员的名称 public int ReputationPoints { get; set; }//人品如何 }
//拍卖中的报价 public class Bid { public Member Menber { get; set; }//谁的报价 public DateTime DatePlaced { get; set; }// public decimal BidAmount { get; set; }//价格 }
//拍卖的物品类 public class Item { public int ItemID { get; private set; }//拍卖物品主键 public string Title { get; set; }//拍卖物品的名称 public string Description { get; set; }//拍卖物品的描述 public DateTime AuctionEndDate { get; set; }//拍卖结束时间 public IList<Bid> Bids { get; set; }//该拍卖物品的报价集合 }
好,这样设计类,不是这篇总结的重点。重点是如何进行后面的单元测试。
然后,是业务操作的代码
public interface IMembersRepository { void AddMember(Member member);//添加 Member FetchByLoginName(string loginName);//根据用户名获取 void SubmitChanges();//提交 }
然后,我在网站项目中会用编辑的功能,其中在Admin控制器中有ChangeLoginName,修改名称的功能。
public class AdminController : Controller { // // GET: /Admin/ IMembersRepository memberRepository;//成员的业务接口
//构造函数 public AdminController(IMembersRepository repositoryParam) { memberRepository = repositoryParam; }
//修改用户名 public ActionResult ChangeLoginName(string oldLoginParam,string newLoginParam) { Member member= memberRepository.FetchByLoginName(oldLoginParam);//业务中的方法 member.LoginName = newLoginParam;//修改名称 memberRepository.SubmitChanges();//提交 return View(); } }
我们需要测试的是,ChangeLoginName是否可以。
新建测试项目
测试之前,要实现接口,新建一个FakeMembersRepository类,使用了IMembersRepository接口的一种测试特有的模仿实现,以模仿特定的条件,即在存储库中有一个成员Bob时的情况。
public class FakeMembersRepository:IMembersRepository { public List<Member> Members = new List<Member>(); public bool DidSubmitChanges = false; public void AddMember(Member member) { throw new NotImplementedException();//先用不到 } public Member FetchByLoginName(string loginName) { return Members.First(m => m.LoginName == loginName);//查找实体通过用户名 } public void SubmitChanges() { DidSubmitChanges = true;//确定提交完成 } }
[TestMethod] public void CanChangeLoginName() { // // TODO: 在此处添加测试逻辑 // //布置 Member bob = new Member() { LoginName = "Bob" };//新创建一个拍卖人员 FakeMembersRepository repositoryParam = new FakeMembersRepository(); repositoryParam.Members.Add(bob); AdminController target = new AdminController(repositoryParam); string oldLoginParam = bob.LoginName; string newLoginParam = "Anasteig"; //动作 target.ChangeLoginName(oldLoginParam, newLoginParam); //断言 Assert.AreEqual(newLoginParam, bob.LoginName); Assert.IsTrue(repositoryParam.DidSubmitChanges); }
新创建一个拍卖人员Bob,使用测试时实现IMembersRepository的FakeMembersRepository类。
将Bob添加到FakeMembersRepository的Members集合中,开始测试AdminController中的ChangeLoginName方法,就这是上面的代码。
最终的断言,是对象中用户名是否修改了!
ps:如何保证你的单元测试,能确保 经过你的功能了(这篇文字是,如何确定调用ChangeLoginName后修改了名称,修改完成后对象的名字和一开始的newLoginParam作对比,是否相同)