using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Moq;
using Moq.Internals;
using Moq.Language;
using Moq.Protected;

using Xunit;
using Xunit.Abstractions;
using Xunit.Extensions;
using Xunit.Sdk;

using MoqStudy.MockModel;

namespace MoqStudy.Test
{
    /// <summary>
    /// Moq 模拟框架学习
    /// </summary>
    public class MoqStudyTest
    {
        #region 创建Mock对象
        /// <summary>
        /// 使用默认设置创建默认对象
        /// </summary>
        [Fact]
        public void Create_Default_Mock_Test()
        {
            var mock = new Mock<Teacher>();
            mock
                .Setup(t => t.Add())
                .Returns(88);
            var teacher = mock.Object;

            Assert.NotNull(teacher);
            Assert.Equal(0, teacher.GroupId);
            Assert.Equal(88, teacher.Add());
        }

        /// <summary>
        /// 给对象构造函数传递参数,创建对象
        /// </summary>
        [Fact]
        public void Create_Params_Mock_Test()
        {
            var groupId = 8;//Teacher类,构造函数的参数
            var addResult = 88;
            var mock = new Mock<Teacher>(groupId);
            mock.Setup(t => t.Add()).Returns(addResult);
            var teacher = mock.Object;

            Assert.NotNull(teacher);
            Assert.Equal(groupId, teacher.GroupId);
            Assert.Equal(addResult, teacher.Add());
        }

        /// <summary>
        /// 使用MockBehavior选项设置,创建默认对象
        /// MockBehavior.Default 默认值即是 MockBehavior.Loose  
        /// MockBehavior.Loose 宽松模式:未显式设置的,取默认值
        /// MockBehavior.Strict 严格模式:未显式设置的,报异常
        /// </summary>
        [Fact]
        public void Create_MockBehavior_Mock_Test()
        {
            var mock = new Mock<Teacher>(MockBehavior.Loose);
            mock.Setup(t => t.Add()).Returns(88);
            var teacher = mock.Object;

            Assert.NotNull(teacher);
            Assert.Equal(0, teacher.GroupId);
            Assert.Equal(88, teacher.Add());
        }

        /// <summary>
        /// 使用MockBehavior选项设置,并传递参数给构造函数,创建对象
        /// </summary>
        [Fact]
        public void Create_MockBehaviorAndParams_Mock_Test()
        {
            var groupId = 9;
            var addResult = 88;

            var mock = new Mock<Teacher>(MockBehavior.Loose, groupId);
            mock.Setup(t => t.Add()).Returns(addResult);
            var teacher = mock.Object;

            Assert.NotNull(teacher);
            Assert.Equal(groupId, teacher.GroupId);
            Assert.Equal(addResult, teacher.Add());
        }
        #endregion
    }
}