OA项目CRUD和单元测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OA项目CRUD和单元测试相关的知识,希望对你有一定的参考价值。

使用ModeFirst方法生成数据库,EntityFramework5.0。

一:Model层的模型:(根据模型生成数据库)

 

二:Dal层的UserInfo代码:

namespace SunOA.EFDAL
{
    public class UserInfoDal
    {
        //crud
        DataModelContainer db = new DataModelContainer();
        public UserInfo GetUserInfoById(int id)
        {
           
            return db.UserInfo.Find(id);
        }

        public List<UserInfo> GetAllUserInfo(int id)
        {
            return db.UserInfo.ToList();
        }

        /// <summary>
        /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合  取代上面的两个查询方法
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public IQueryable<UserInfo> GetUsers(Expression<Func<UserInfo,bool>> whereLambda)
        {
            return db.UserInfo.Where(whereLambda).AsQueryable();
        }

        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public UserInfo Add(UserInfo userInfo)
        {
            db.UserInfo.Add(userInfo);
            db.SaveChanges();
            return userInfo;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public bool Update(UserInfo userInfo)
        {
            //db.Entry(userInfo).State = EntityState.Unchanged;
            //上面的代码等价于下面的这个代码
          //  db.UserInfo.Attach(userInfo);  //整体修改
            db.Entry(userInfo).State = EntityState.Modified;   //修改方法中的一个属性
            return  db.SaveChanges()>0;

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public bool Delete(UserInfo userInfo)
        {
            db.Entry(userInfo).State = EntityState.Deleted;
            return db.SaveChanges() > 0;

        }

    }
}

分页的代码:

         /// <summary>
        /// 分页的语句
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="total"></param>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<UserInfo> GetPageUsers<S>(int pageSize, int pageIndex, out int total,
            Expression<Func<UserInfo, bool>> whereLambda,
            Expression<Func<UserInfo,S>> orderByLambda,
           bool isAsc)
        {
            total = db.UserInfo.Where(whereLambda).Count();
            if (isAsc)
            {
                var temp = db.UserInfo.Where(whereLambda).OrderBy<UserInfo, S>(orderByLambda).Skip(pageSize*(pageIndex - 1))
              .Take(pageSize).AsQueryable();
                return temp;
            }
            else
            {
                var temp = db.UserInfo.Where(whereLambda).OrderByDescending<UserInfo, S>(orderByLambda).Skip(pageSize*(pageIndex - 1))
              .Take(pageSize).AsQueryable();
                return temp;
            }
      
        }

单元测试:(引入Model和Dal)

namespace SunOA.UnitTest
{
    [TestClass, System.Runtime.InteropServices.GuidAttribute("7651815F-CEE5-4E48-9CCF-4032C79CA9B8")]
    public class UserInfoDalTest
    {
        [TestMethod]
        public void GetUsers()
        {
            //测试  获取数据的方法
            UserInfoDal dal = new UserInfoDal();

            //单元测试必须自己处理数据,不能依赖第三方数据  如果依赖数据那么先自己创建数据,用完之后再清除数据
            for (int i = 0; i < 10; i++)
            {
                dal.Add(new UserInfo()
                {
                    UName=i+"sun"
                });
            }
         IQueryable<UserInfo> temp= dal.GetUsers(u => u.UName.Contains("su"));

            //断言
         Assert.AreEqual(true, temp.Count() >= 10);
        }
    }
}

 执行成功数据库会插入数据:

在添加一个Model类,又得有对应的CRUD方法,所以封装一个BaseDal的公用Dal。

 /// <summary>
    /// 职责:封装所有Dal的公共CRUD
    /// </summary>
   public class BaseDal<T> where T:class,new()
    {
        DataModelContainer db = new DataModelContainer();
       

        /// <summary>
        /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合  取代上面的方法
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda)
        {
            return db.Set<T>().Where(whereLambda).AsQueryable();
        }

        /// <summary>
        /// 分页的语句
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="total"></param>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total,
            Expression<Func<T, bool>> whereLambda,
            Expression<Func<T, S>> orderByLambda,
           bool isAsc)
        {
            total = db.Set<T>().Where(whereLambda).Count();
            if (isAsc)
            {
                var temp = db.Set<T>().Where(whereLambda).OrderBy<T, S>(orderByLambda).Skip(pageSize * (pageIndex - 1))
              .Take(pageSize).AsQueryable();
                return temp;
            }
            else
            {
                var temp = db.Set<T>().Where(whereLambda).OrderByDescending<T, S>(orderByLambda).Skip(pageSize * (pageIndex - 1))
              .Take(pageSize).AsQueryable();
                return temp;
            }

        }

        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
        public T Add(T entity)
        {
            db.Set<T>().Add(entity);
            db.SaveChanges();
            return entity;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            //db.Entry(T).State = EntityState.Unchanged;
            //上面的代码等价于下面的这个代码
            //  db.T.Attach(T);  //整体修改
            db.Entry(entity).State = EntityState.Modified;   //修改方法中的一个属性
            return db.SaveChanges() > 0;

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(T entity)
        {
            db.Entry(entity).State = EntityState.Deleted;
            return db.SaveChanges() > 0;
        }

    }

 UserInfoDal:和  OrderInfoDal继承BaseDal

 public  class OrderInfoDal:BaseDal<OrderInfo>
    {

    }
public class UserInfoDal:BaseDal<UserInfo>
{

}

 BLL层  UserInfoService:

namespace SunOA.BLL
{
    //模块内高内聚,低耦合

    //变化点:1.跨数据库

    //先用接口隔离具体的实现
   
    public class UserInfoService
    {
        //不管new哪个Dal 下面都没有任何变化
        IUserInfoDal userInfoDal=new UserInfoDal();  NhUserInfoDal();
        public UserInfo Add(UserInfo userInfo)
        {
            return userInfoDal.Add(userInfo);
        }
    }
}

 OrderInfoService:(如果多的话都得修改)

namespace SunOA.BLL
{
   public class OrderInfoService
    {
       public OrderInfo Add(OrderInfo orderInfo)
       {
           IUserInfoDal userInfoDal = new UserInfoDal();  NhUserInfoDal(); 这是变化点
           return orderInfo;
       }
    }
}

 

层与层依赖于接口IBaseDal:

 public interface IBaseDal<T> where T:class,new()
    {
        /// <summary>
        /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合  取代上面的方法
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
       IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda);
        

        /// <summary>
        /// 分页的语句
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="total"></param>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
         IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total,
            Expression<Func<T, bool>> whereLambda,
            Expression<Func<T, S>> orderByLambda,
           bool isAsc);
      
        

        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
         T Add(T entity);
      

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
         bool Update(T entity);
       

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
         bool Delete(T entity);
        
    }

 所有类的接口继承于IBaseDal:

 public interface IOrderInfoDal:IBaseDal<OrderInfo>
    {

    }
public interface IUserInfoDal:IBaseDal<UserInfo>
    {

    }

 UserInfoDal和OrderInfoDal分别实现IUserInfoDal和IOrderInfoDal接口。

public  class OrderInfoDal:BaseDal<OrderInfo>,IOrderInfoDal
 public class UserInfoDal:BaseDal<UserInfo>,IUserInfoDal

 写一个静态工厂:

 public class StaticDalFactory
    {
        public static IUserInfoDal GetUserInfoDal()
        {
            return new UserInfoDal();
        }
    }
OrderInfoService和UserInfoService:
 public class OrderInfoService
    {
       public OrderInfo Add(OrderInfo orderInfo)
       {
           IUserInfoDal userInfoDal = StaticDalFactory.GetUserInfoDal();
           return orderInfo;
       }
    }
        //静态工厂
        private IUserInfoDal UserInfoDal = StaticDalFactory.GetUserInfoDal();

        public UserInfo Add(UserInfo userInfo)
        {
            return userInfoDal.Add(userInfo);
        }
 public static IOrderInfoDal GetOrderInfoDal()
        {
            return new OrderInfoDal();
        }

 

抽象工厂的实现:

引用命名空间:

using System.Reflection;

 WebConfig中的配置:

  <appSettings>
   <!--抽象工厂创建数据库访问层实例所在的 程序集的名称-->
    <add key="DalAssemblyName" value="SunOA.EFDAL" />
 </appSettings>

 静态工厂:

  public class StaticDalFactory
    {
       public static string assemblyName = System.Configuration.ConfigurationManager.AppSettings["DalAssemblyName"];
        public static IUserInfoDal GetUserInfoDal()
        {
           // return new UserInfoDal();
            //把new去掉 改一个配置创建实体就发生变化,不需要改代码
         
          return Assembly.Load(assemblyName).CreateInstance(assemblyName + ".UserInfoDal") as IUserInfoDal;
        }

        public static IOrderInfoDal GetOrderInfoDal()
        {
            return Assembly.Load(assemblyName).CreateInstance(assemblyName + ".OrderInfoDal") as IOrderInfoDal;
        }
    }

 Service层的代码:

private IUserInfoDal UserInfoDal = StaticDalFactory.GetUserInfoDal();

        public UserInfo Add(UserInfo userInfo)
        {
            return UserInfoDal  .Add(userInfo);
        }

 IBaseServie的代码:

 public interface IBaseService<T> where T :class,new()
    {
       IQueryable<T> GetEntities(Expression<Func<T, bool>> whereLambda);

       IQueryable<T> GetPageEntities<S>(int pageSize, int pageIndex, out int total,
           Expression<Func<T, bool>> whereLambda,
               Expression<Func<T, S>> orderByLambda,
           bool isAsc);


       T Add(T entity);
       bool Update(T entity);
       bool Delete(T entity);

    }

 BaseService的代码:

namespace SunOA.BLL
{
    /// <summary>
    /// 父类要逼迫自己给父类的一个属性赋值  赋值的操作必须在父类的方法调用之前执行
    /// </summary>
    /// <typeparam name="T"></typeparam>
   public  abstract  class BaseService<T> where T:class  ,new()
    {
       public IBaseDal<T> CurrentDal { get; set; }

       /// <summary>
       /// DbSession 做成属性
       /// </summary>
       public IDbSession DbSession 
       {
           get { return  DbSessionFactory.GetCurrentDbSession(); }
       }

       /// <summary>
       /// 基类的构造函数
       /// </summary>
       public BaseService()
       { 
         //调用了抽象方法
           SetCurrentDal();
       }

       //抽象方法:要求子类必须实现抽象方法,对此方法进行重写
       public abstract void SetCurrentDal();  



        /// <summary>
        /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合  取代上面的方法
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
       public IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda)
       {
           return CurrentDal.GetEntites(whereLambda);
       }



        /// <summary>
        /// 分页的语句
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="total"></param>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
       public IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total,
           Expression<Func<T, bool>> whereLambda,
           Expression<Func<T, S>> orderByLambda,
          bool isAsc)
       {
           return CurrentDal.GetPageEntites(pageSize, pageIndex, out total, whereLambda, orderByLambda, isAsc);
       }



        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
        public T Add(T entity)
        { 
            CurrentDal.Add(entity);
            DbSession.SaveChanges();
            return entity;

        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="T"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            CurrentDal.Update(entity);
            return DbSession.SaveChanges() > 0;
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(T entity)
        {
            CurrentDal.Delete(entity);
            return DbSession.SaveChanges() > 0;
        }
    }
}

IOrderInfoService的代码:

 public interface IUserInfoService:IBaseService<UserInfo>
    {

    }

 

OrderInfoService的代码:

   public class OrderInfoService:BaseService<OrderInfo>
    {
      
       /// <summary>
       /// 赋值给当前的Dal
       /// </summary>
        public override void SetCurrentDal()
        {
            CurrentDal = DbSession.OrderInfoDal;
        }
    }

 控制器中的代码:

 public class UserInfoController : Controller
    {
        //
        // GET: /UserInfo/
        UserInfoService userInfoService = new UserInfoService();
        public ActionResult Index()
        {
            ViewData.Model = userInfoService.GetEntites(u => true); 
            return View();
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(UserInfo userInfo)
        {
            if (ModelState.IsValid)
            {

                userInfoService.Add(userInfo);

            }
            return RedirectToAction("Index");
        }

    }

 前台代码自动生成。最后进行展示。

以上是关于OA项目CRUD和单元测试的主要内容,如果未能解决你的问题,请参考以下文章

在测试之间传递JUnit数据

MyBatisMyBatis CRUD操作单元测试的使用${} 与 #{} 的区别

junit4单元测试--web项目中模拟登录会话,做全流程测试

单元测试很棒,但是

第1129期对vue.js单文件(.vue)进行单元测试

单元测试 NPE,当我添加片段自定义转换时