using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Moq;
using Moq.Internals;
using Moq.Language;
using Moq.Protected;
using xUnitStudy.IBll;
using xUnitStudy.Bll;
using xUnitStudy.IDal;
using xUnitStudy.Model;

namespace xUnitStudy.WebApi.Test
{
    public class StudentBllTest:IDisposable
    {
        #region 准备
        private StudentBll actualBll;
        public StudentBllTest()
        {
            //这里创建和设置需要注入的IDal。当然也可以创建和设置,直接注入。
            actualBll = new Bll.StudentBll();
        }
        #endregion

        [Fact]
        public void Students_Test()
        {
            IStudentBll actual_Bll = new StudentBll();
            List<Student> studentsFromProperty = actual_Bll.Students;
            List<Student> studentsFromMethod = actual_Bll.GetAll();

            Assert.Equal(studentsFromMethod, studentsFromProperty);
        }

        [Fact]
        public void GetAll_Test()
        {
            List<Student> students = actualBll.GetAll();

            Assert.Equal(actualBll.Students, students);
        }

        [Fact]
        public void GetStudentById_Test()
        {
            var studentId = 1;

            Student student = actualBll.GetStudentById(studentId);

            Assert.NotNull(student);
            Assert.Equal(studentId, student.Id);
        }

        [Fact]
        public void AddStudent_Test()
        {
            var exitsStudent = new Student() { Id=1,Name="lishi",Age=40,lever=0};
            var newStudent = new Student() { Id=100,Name="wangwu",Age=30,lever=0};

            var exitsResult = actualBll.AddStudent(exitsStudent);
            var newResult = actualBll.AddStudent(newStudent);

            Assert.False(exitsResult.result);

            Assert.True(newResult.result);
            Assert.Contains(newStudent, actualBll.GetAll());
        }

        [Fact]
        public void UpdateStudent_Test()
        {
            var exitsStudent = new Student() { Id = 1, Name = "lishi", Age = 40, lever = 0 };
            var newStudent = new Student() { Id = 100, Name = "wangwu", Age = 30, lever = 0 };

            var exitsResult = actualBll.UpdateStudent(exitsStudent);
            var newResult = actualBll.UpdateStudent(newStudent);

            Assert.True(exitsResult.result);
            Assert.Contains(exitsStudent, actualBll.GetAll());

            Assert.False(newResult.result);
        }

        [Fact]
        public void DeleteStudent_Test()
        {
            var exitsStudent = new Student() { Id = 1, Name = "lishi", Age = 40, lever = 0 };
            var newStudent = new Student() { Id = 100, Name = "wangwu", Age = 30, lever = 0 };

            var exitsResult = actualBll.DeleteStudent(exitsStudent.Id);
            var newResult = actualBll.DeleteStudent(newStudent.Id);

            Assert.True(exitsResult);
            Assert.DoesNotContain(exitsStudent, actualBll.GetAll());

            Assert.False(newResult);
        }

        /// <summary>
        /// 获取学费
        /// 属性注入:IDal Mock对象
        /// </summary>
        [Fact]
        public void GetTuition_UseMoq_Test()
        {
            // #准备
            Mock<IStudentDal> mockStudentDal = new Mock<IStudentDal>();
            mockStudentDal
                .Setup(m => m.GetStudentById(2))
                .Returns
                (
                    new Student() { Id = 2, Name = "小小张", Age = 95 }
                );

            //属性注入,也可以使用构造函数注入
            actualBll.dal = mockStudentDal.Object;

            // #使用
            var student = actualBll.GetStudentById(2);
            var tuition = actualBll.GetTuition(2);

            // #断言
            Assert.Equal(student.Id + student.Age, tuition);
        }

        #region 清理
        public void Dispose()
        {
             
        }
        #endregion
    }
}