有志者、事竟成,破釜沉舟,百百二秦关终属楚;苦心人、天不负,卧薪尝胆,三千越甲可吞吴。

拂晓犬吠

学习中遇到困难是很正常的事情,不要苦恼,不要气馁,恰恰相反,应该兴奋,因为又学到知识了,需要不断提高自己应对问题和解决问题的能力和信心。

学习单元测试(一)简单业务中的单元测试

  定义领域模型

  业务是描述拍卖物品的场景。一组拍卖人,每个拍卖人都有一组报价。每个报价都针对一个物品,而每个物品可以有不同拍卖人的多个报价。

  

    //拍卖 成员类
    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作对比,是否相同)

posted @ 2019-05-21 14:21  ID拂晓犬吠  阅读(395)  评论(0编辑  收藏  举报