Moq mock测试相关



什么是Moq?

Moq(英语发音是Mock-you 或者只是mock)是一个针对.Net开发的模拟库,它从开始就完全充分利用了.NET3.5(LINQ表达式树)和C#3.0的新特性(lambda表达式)。它的目标是让模拟以一种自然的方式与现有单元测试进行集成,使它更加简单、直观,以避免开发人员被迫重写测试或高成本的学习测试框架。这使它成为了一个高生产力、类型安全、重构友好的模拟库。



从哪得到Moq?

如果你看过我的其他文章,我们可以直接使用 VS中的插件Nuget来获取Moq并且引用到指定的项目。



可以模拟什么?局限性


 


首先,模拟的类不能是密封的。



其次,你不能直接模拟静态方法。因为Moq只能创建模拟对象实例。在这种情况下,间接的解决方案是我们可以在要模拟对象外包装一层,并且去模拟这个新对象。这种模式被称为适配器模式。



通常我们测试一个方法,它有可能调用好几个service。但是每次都去访问这些service的代价是很高的。我们可以通过模拟的方法让它模拟访问service,并且根据不同请求模拟返回响应的结果。



Moq原理

 


Moq是如何办到的?它只需要一个接口类型就可以生产一个对象?没错,就是这样。Moq使用 Castle DynamicProxy 完成这个任务。基本原理就是它利用反射机制的 Emit 功能动态生成一个空类型(也就是所有接口的方法都实例化,但是没有任何功能,只是一个程序骨架)。所以Mock的能力就在于可以利用DynamicProxy的机制快速生产出一个假对象来,用于模仿真对象的行为。



什么是 Mock 对象?



Mock 对象是用来隔离测试依赖目标的技术,通过隔离使得我们可以细粒度地测试单个类中的单个方法, 可能在依赖的类完全实现之前进行。隔离可以使你的测试更快进行,使得测试一小片功能更加容易。当你通过隔离完成分离的一部分测试之后,就可以有信心进行更大粒度的测试,当你在处理像数据访问层或者 Web 服务层的依赖的时候,隔离会更有意义,外部的调用会花费很多的时间,或者在远程系统当机的时候可能会失败。


对于使用 Mock 对象来说,重要的是逼迫你考虑你的类和方法依赖的东西,它强迫你考虑你的类之间的耦合性,如果耦合性很高的话,就很难测试,如果耦合性弱的话,就非常容易测试。有关这些早期概念设计的考虑可以帮助你更加轻松地管理随时间推移带来变化。



为什么要用Mock?

在测试过程中,往往会遇到这些问题:


(1)真实对象具有不可确定的行为(产生不可预测的结果,如股票行情)。 


(2)真实对象很难被创建。 


(3)真实对象的某些行为很难触发(如网络错误)。


(4)真实对象令程序的运行速度很慢。 


(5)真实对象有(或者是)用户界面。 


(6)测试需要询问真实对象它是如何被调用的(例如,测试可能需要验证某个回调函数是否被调用了)。 


(7)真实对象实际上并不存在(当需要和其他开发小组,或者新的硬件系统打交道的时候,这是一个普遍问题)。 


借助于mock对象,我们就可以解决上面提到的所有问题。



测试方法



 // 准备 Mock IFoo 接口


 var mock = new Mock<IFoo>(); 


 // 配置准备模拟的方法,当调用接口中的 DoSomething 方法,并传递参数 "bing" 的时候,返回 true


 mock.Setup(foo => foo.DoSomething("ping")).Returns(true);   


 


 // 方法的参数中使用了 out 参数


 // out arguments 


 var outString = "ack"; 


 // 当调用 TryParse 方法的时候,out 参数返回 "ack", 方法返回 true, lazy evaluated 


 mock.Setup(foo => foo.TryParse("ping", out outString)).Returns(true);   


 


 // ref 参数


 var instance = new Bar(); 


 // 仅仅在使用 ref 调用的时候,才会匹配下面的测试


 mock.Setup(foo => foo.Submit(ref instance)).Returns(true);  


  


 // 当方法返回值得时候,还可以访问返回的值


 // 这里可以使用多个参数


 mock.Setup(x => x.DoSomething(It.IsAny<string>()))


                  .Returns((string s) => s.ToLower()); 


 


 // 在被调用的时候抛出异常


 mock.Setup(foo => foo.DoSomething("reset")).Throws<InvalidOperationException>(); 


 mock.Setup(foo => foo.DoSomething("")).Throws(new ArgumentException("command");   


 


 // 延迟计算返回的结果 


 mock.Setup(foo => foo.GetCount()).Returns(() => count);   


 


 // 在每一次调用的时候,返回不同的值 


 var mock = new Mock<IFoo>(); 


 var calls = 0; 


 mock.Setup(foo => foo.GetCountThing())


      .Returns(() => calls)


      .Callback(() => calls++); 


 


 // 第一次调用返回 0, 下一次是 1, 依次类推


 Console.WriteLine(mock.Object.GetCountThing());



匹配参数

 // 任意值 


 mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(true);   


 


 // 提供的值必须匹配一个函数, lazy evaluated 


 mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);    


 


 // 匹配一个范围 


 mock.Setup(foo => foo.Add(It.IsInRange<int>(0, 10, Range.Inclusive))).Returns(true);    


 


 // 匹配正则表达式


 mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");



属性



 // 普通属性


 mock.Setup(foo => foo.Name).Returns("bar");   


 


 // 多层的属性


 mock.Setup(foo => foo.Bar.Baz.Name).Returns("baz");  


 


 // 期望设置属性的值为 "foo" 


 mock.SetupSet(foo => foo.Name = "foo");  


 


 // 或者直接验证赋值 


 mock.VerifySet(foo => foo.Name = "foo");



设置属性,以便自动跟踪它的值



 // 开始 "tracking" 属性的 sets/gets 


 mock.SetupProperty(f => f.Name);  


 


 // 提供一个默认的值


 mock.SetupProperty(f => f.Name, "foo");   


 


 // 现在,你可以:  


 IFoo foo = mock.Object; 


 


 // 保存的值 


 Assert.Equal("foo", foo.Name);  


 


 // 重新设置一个值


 foo.Name = "bar"; 


 Assert.Equal("bar", foo.Name);


 


还可以准备所有的属性



mock.SetupAllProperties();


 


事件



 // 抛出一个事件 


 mock.Raise(m => m.FooEvent += null, new FooEventArgs(fooValue));  


 


 // 多层的后代中的事件 


 mock.Raise(m => m.Child.First.FooEvent += null, new FooEventArgs(fooValue));  


 


 // 当 Submit 方法被调用的时候,抛出一个事件 


 mock.Setup(foo => foo.Submit()).Raises(f => f.Sent += null, EventArgs.Empty); 


 


 // 抛出异常将会触发对象底层的行为


 // 你可能需要在后面进行断言处理


 


 // 抛出一个自定义的事件


 public delegate void MyEventHandler(int i, bool b); 


 public interface IFoo {   event MyEventHandler MyEvent;  }  


 var mock = new Mock<IFoo>(); 


 ... 


 


 // 传递自定义的事件参数


 mock.Raise(foo => foo.MyEvent += null, 25, true);


 


 回调

 var mock = new Mock<IFoo>(); 


 mock.Setup(foo => foo.Execute("ping"))


      .Returns(true)


      .Callback(() => calls++);   


 


 // 使用调用的参数 


 mock.Setup(foo => foo.Execute(It.IsAny<string>()))


      .Returns(true)


      .Callback((string s) => calls.Add(s));  


 


 // 使用泛型语法 


 mock.Setup(foo => foo.Execute(It.IsAny<string>()))


      .Returns(true)


      .Callback<string>(s => calls.Add(s));  


 


 // 使用多个参数


 mock.Setup(foo => foo.Execute(It.IsAny<int>(), It.IsAny<string>()))


      .Returns(true)


      .Callback<int, string>((i, s) => calls.Add(s));  


 


 // 调用之前和之后的回调 


 mock.Setup(foo => foo.Execute("ping"))


      .Callback(() => Console.WriteLine("Before returns"))


      .Returns(true)


      .Callback(() => Console.WriteLine("After returns"));


 


验证



 mock.Verify(foo => foo.Execute("ping"));  


 


 // 在验证失败的时候,提供自定义的错误提示信息 


 mock.Verify(foo => foo.Execute("ping"), "When doing operation X, the service should be pinged always");  


 


 // 从没有被调用的方法 


 mock.Verify(foo => foo.Execute("ping"), Times.Never());  


 


 // 至少调用过一次 


 mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce());  


 mock.VerifyGet(foo => foo.Name);  


 


 // 验证对属性的赋值. 


 mock.VerifySet(foo => foo.Name);  


 


 // 验证对于属性设置特定的值 


 mock.VerifySet(foo => foo.Name ="foo");  


 


 // 验证匹配的参数 


 mock.VerifySet(foo => foo.Value = It.IsInRange(1, 5, Range.Inclusive));



 自定义 Mock 行为

Mock 的行为分为严格的 Strict 和宽松的 Loose, 默认为宽松的。在严格模式下,使用任何没有被指定的行为,都将会抛出异常,宽松模式下,不会抛出任何异常,方法将会返回默认值或者空的数组等等。



var mock = new Mock<IFoo>(MockBehavior.Strict);


 


如果没有重写基类的实现,默认将不会调用基类,在 Mock Web/Html 控件的是必须的。



var mock = new Mock<IFoo> { CallBase = true };


 


 创造自动递归的 Mock, Mock 对象对于它的任何成员将会返回一个新的 Mock 对象。




var mock = new Mock<IFoo> { DefaultValue = DefaultValue.Mock }; 



// 默认是 DefaultValue.Empty  


// 现在这个属性将会返回一个新的 Mock 对象 


IBar value = mock.Object.Bar;  




// 可以使用返回的 Mock 对象, 后即对属性的访问返回相同的对象实例


// 这就允许我们可以进行后继的设置  


// set further expectations on it if we want 


var barMock = Mock.Get(value); 


barMock.Setup(b => b.Submit()).Returns(true);



中心化的 Mock 实例创建和管理:你可以在一个地方使用 MockRepository 创建和验证所有的 Mock 对象,设置 MockBehavior, CallBse 和 DefaultValue 约束。



var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };  



// 创建 Mock 对象


var fooMock = factory.Create<IFoo>();  



// 在创建的时候重写仓库的设置 


var barMock = factory.Create<IBar>(MockBehavior.Loose);  




// 验证通过仓库创建的对象 


factory.Verify();


 


其它



// 用在测试用例的开始 


using Moq.Protected()  




// 测试中


var mock = new Mock<CommandBase>(); mock.Protected()


      .Setup<int>("Execute")


      .Returns(5);  




// 如果用到了参数匹配, 必须使用 ItExpr 来代替 It 


// 以后计划改进


mock.Protected()


     .Setup<string>("Execute",         ItExpr.IsAny<string>())


     .Returns(true);


高级特性

 // 从 Mock 实例重新获得 Mock 对象


 IFoo foo = // get mock instance somehow 


 var fooMock = Mock.Get(foo); 


 fooMock.Setup(f => f.Submit()).Returns(true);   


 


 // 实现多个接口 


 var foo = new Mock<IFoo>(); 


 var disposableFoo = foo.As<IDisposable>(); 


 


 // 现在 IFoo mock 已经实现了接口 IDisposable :) disposableFoo.Setup(df => df.Dispose());   


 


 // 定制匹配 


 mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); ... 


 public string IsLarge()  


 {


     return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); 


 }


 


 一个完整的测试类

 


 using System;


using System.Collections.Generic;


using System.Reflection;


using System.Threading;


using System.Threading.Tasks;


using HQ.Job.ISmsUtils;


using HQ.Job.Test.Base;


using Moq;


using NUnit.Framework;




namespace HQ.Job.Business.Push.Tests


{


    [TestFixture()]


    public class SmsSendBusinessTests


    {


        private Mock<ISmsSendUtil> _smsSendUtilMock;


        private Mock<ISmsSendUtil> _smsSendUtilMock2;


        private Mock<ISmsSendHttpUtil> _smsSendHttpUtilMock;




        [TestFixtureSetUp]


        public void TestFixtureSetUp()


        {


            //强制使用本测试工程的默认配置,防止多个测试同时运行时的配置共用混乱


            AppConfig.Change(Assembly.GetExecutingAssembly().GetName().CodeBase + ".config");


        }


        [SetUp]


        public void SetUp()


        {


            _smsSendUtilMock = new Mock<ISmsSendUtil>();


            _smsSendUtilMock2 = new Mock<ISmsSendUtil>();


            _smsSendHttpUtilMock = new Mock<ISmsSendHttpUtil>();


        }


        private SmsSendBusiness CreateSmsSendBusiness()


        {


            return new SmsSendBusiness();


        }


        private SmsSendBusiness CreateSmsSendBusiness3Parallel()


        {


            return new SmsSendBusiness(3);


        }


        private SmsSendBusiness CreateSmsSendBusiness2Parallel()


        {


            return new SmsSendBusiness(2);


        }




        [Test()]


        public void AddSendUtilTest()


        {


            var smsSendBusiness = CreateSmsSendBusiness();


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);


            Assert.AreEqual(1, smsSendBusiness.GetSendObjectNum());




            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台B");


            ISmsSendUtil smsSendUtil1 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil1);


            Assert.AreEqual(2, smsSendBusiness.GetSendObjectNum());




        }




        [Test()]


        public async void AddSendMsgTest()


        {


           


            var smsSendBusiness = CreateSmsSendBusiness();


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000111");


            Assert.AreEqual(smsSendBusiness.GetWaitSendMsgNumber(), 1);




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000111");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000111");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000111");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000111");


            Assert.AreEqual(smsSendBusiness.GetWaitSendMsgNumber(), 5);




            //把添加的消息处理掉


            //初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");


            var list1 = new List<int>();


            _smsSendUtilMock.Setup(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .ReturnsAsync(new SmsMessageResult() { Result = "1", Content = "000000", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = list1, Time = DateTime.Now });


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


            }


        }




        [Test()]


        public void DoLoopTest_一个平台_发送全失败()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            var ismsNum = smsSendBusiness.GetWaitSendMsgNumber();


            //初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");


            var list1 = new List<int>();


            _smsSendUtilMock.Setup(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .ReturnsAsync(new SmsMessageResult() { Result = "0", Content = "000000", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = list1, Time = DateTime.Now });


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum, ismsNum);




        }




        [Test()]


        public void DoLoopTest_一个平台_发送全成功()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            //初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");


            var list1 = new List<int>();


            _smsSendUtilMock.Setup(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .ReturnsAsync(new SmsMessageResult() { Result = "1", Content = "000000", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = list1, Time = DateTime.Now });


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


                Thread.Sleep(1 * 1000);


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum, 6);


        }




        [Test()]


        public void DoLoopTest_平台B发送成功_平台A发送失败_结果全通过B发送成功()


        {


            //初始化待发送消息




            var smsSendBusiness = CreateSmsSendBusiness();


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");






            #region 初始化发送实例




            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time.AddMilliseconds(1) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time.AddMilliseconds(2) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time.AddMilliseconds(3) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time.AddMilliseconds(4) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time.AddMilliseconds(5) }))


                .Returns(


                    Task.Run<SmsMessageResult>(


                        () =>


                            new SmsMessageResult()


                            {


                                Result = "0",


                                Content = "111111",


                                Mobile = "14500000000",


                                SendObjIndex = 0,


                                SendObjIndexList = new List<int> { 1 },


                                Time = time.AddMilliseconds(6)


                            }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = time.AddMilliseconds(1) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = time.AddMilliseconds(2) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = time.AddMilliseconds(3) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = time.AddMilliseconds(4) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = time.AddMilliseconds(5) }))


                .Returns(


                    Task.Run<SmsMessageResult>(


                        () =>


                            new SmsMessageResult()


                            {


                                Result = "1",


                                Content = "222222",


                                Mobile = "14500000000",


                                SendObjIndex = 1,


                                SendObjIndexList = new List<int> { 0 },


                                Time = time.AddMilliseconds(6)


                            }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 10; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum, 6);




        }




        [Test()]


        public void DoLoopTest_平台A发送成功_平台B发送失败_结果全通过A发送成功()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");






            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum, 6);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum, 0);


        }




        [Test()]


        public void DoLoopTest_平台A发送失败_平台B发送失败_结果AB发送失败数和等于两倍信息数_成功数等于0()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");






            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum + smsSendBusiness.ListSmsSendUtilExt[1].SendFailNum, 12);


        }




        [Test()]


        public void DoLoopTest_平台A发送成功_平台B发送成功_结果AB发送成功数和等于信息数_失败数等于0()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");






            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendFailNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum + smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum, 6);


        }




        [Test()]


        public void DoLoopTest_检测任务完成状态()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            var isOk = smsSendBusiness.CheckTaskFinishStatus();


            Assert.AreEqual(isOk, false);




            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 1; i++)


            {


                smsSendBusiness.DoLoop();


            }


            var isOk2 = smsSendBusiness.CheckTaskFinishStatus();


            Assert.AreEqual(isOk2, false);




            for (var i = 0; i < 50; i++)


            {


                smsSendBusiness.DoLoop();


            }




            var isOk3 = smsSendBusiness.CheckTaskFinishStatus();


            Assert.AreEqual(isOk3, true);


        }




        [Test()]


        public void DoLoopTest_并发数测试_3个并发_发6条_不延时_sleep10s_结果小于11秒()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness3Parallel();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = time }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            var startTime = DateTime.Now;


            for (var i = 0; i < 10; i++)


            {


                smsSendBusiness.DoLoop();


                Thread.Sleep(1*1000);


            }


            var endTime = DateTime.Now;


            var totalSecond = new TimeSpan(endTime.Ticks - startTime.Ticks).TotalSeconds;




            Assert.AreEqual(totalSecond<11, true);


        }


//这个测试还有点问题,模拟结果延时返回,看并发的效果,


//但.Callback(() => { 


        //            Thread.Sleep(sleepSeconds);


        //                            iContent1++;


        //       })


//sleep造成了每个调用都阻塞了,还没有找到实际可模拟这个场景的方法


        [Test(), RequiresThread]


        public void DoLoopTest_并发数测试_3个并发_发6条_延时3秒_sleep10s_结果小于14秒()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness3Parallel();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000005", "000005");




            var sleepSeconds = 3 * 1000;


            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            var iContent1 = 111111;


            _smsSendUtilMock.Setup(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                //.Callback(() => Task.Delay(sleepSeconds))


                //.Callback(() => Task.Delay(sleepSeconds).Wait())


                .Callback(() => { 


                    Thread.Sleep(sleepSeconds);


                                    iContent1++;


                })


                .Returns(Task.Run<SmsMessageResult>(() =>


                {


                    //Task.Delay(sleepSeconds).Wait();


                    return new SmsMessageResult()


                    {


                        Result = "1",


                        Content = iContent1.ToString(),


                        Mobile = "14500000000",


                        SendObjIndex = 0,


                        SendObjIndexList = new List<int> {1},


                        Time = time


                    };


                }));








            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);


            var iContent2 = 222222;


            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.Setup(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                //.Callback(() =>


                //{


                //    Task.Delay(sleepSeconds);


                //    iContent2++;


                //})


                //.Callback(() => Task.Delay(sleepSeconds).Wait())


                .Callback(() =>


                {


                    Thread.Sleep(sleepSeconds);


                    iContent2++;


                })


                .Returns(Task.Run<SmsMessageResult>(() =>


                {


                    //Task.Delay(sleepSeconds).Wait();


                    return new SmsMessageResult()


                    {


                        Result = "1",


                        Content = iContent2.ToString(),


                        Mobile = "14500000000",


                        SendObjIndex = 1,


                        SendObjIndexList = new List<int> { 0 },


                        Time = DateTime.Now


                    };


                }));


            //_smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> {0},


            //            Time = DateTime.Now


            //        };


            //    }))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> { 0 },


            //            Time = DateTime.Now


            //        };


            //    }))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> { 0 },


            //            Time = DateTime.Now


            //        };


            //    }))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> { 0 },


            //            Time = DateTime.Now


            //        };


            //    }))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> { 0 },


            //            Time = DateTime.Now


            //        };


            //    }))


            //    .Returns(Task.Run<SmsMessageResult>(() =>


            //    {


            //        Task.Delay(sleepSeconds).Wait();


            //        return new SmsMessageResult()


            //        {


            //            Result = "1",


            //            Content = "222222",


            //            Mobile = "14500000000",


            //            SendObjIndex = 1,


            //            SendObjIndexList = new List<int> { 0 },


            //            Time = DateTime.Now


            //        };


            //    }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            var startTime = DateTime.Now;


            for (var i = 0; i < 5; i++)


            {


                smsSendBusiness.DoLoop();


                Thread.Sleep(1 * 1000);


            }


            var endTime = DateTime.Now;


            var totalSecond = new TimeSpan(endTime.Ticks - startTime.Ticks).TotalSeconds;


            Console.WriteLine("totalSecond = "+totalSecond);


            Console.WriteLine("0 fail="+smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum);


            Console.WriteLine("0 success=" + smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum);


            Console.WriteLine("1 fail=" + smsSendBusiness.ListSmsSendUtilExt[1].SendFailNum);


            Console.WriteLine("1 success=" + smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum);


            //阻塞了,没有并发


            //.Callback(() => { 


            //        Thread.Sleep(sleepSeconds);


            Assert.AreEqual(totalSecond < 25, true);


        }




        [Test()]


        public void DoLoopTest_消息超时测试_发送前超时()


        {


            //初始化待发送消息


            var smsSendBusiness = CreateSmsSendBusiness3Parallel();




            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000000", "000222");


            smsSendBusiness.AddSendMsg(DateTime.Now, "14500000001", "000001");


            smsSendBusiness.AddSendMsg(DateTime.Now.AddDays(-2), "14500000002", "000002");


            smsSendBusiness.AddSendMsg(DateTime.Now.AddDays(-2), "14500000003", "000003");


            smsSendBusiness.AddSendMsg(DateTime.Now.AddDays(-2), "14500000004", "000004");


            smsSendBusiness.AddSendMsg(DateTime.Now.AddDays(-2), "14500000005", "000005");




            #region 初始化发送实例


            _smsSendUtilMock.Setup(e => e.GetSpName()).Returns("平台A");




            var time = DateTime.Now;


            _smsSendUtilMock.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now.AddDays(-2) }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now.AddDays(-2) }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now.AddDays(-2) }))


            .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "0", Content = "111111", Mobile = "14500000000", SendObjIndex = 0, SendObjIndexList = new List<int> { 1 }, Time = DateTime.Now.AddDays(-2) }));


            ISmsSendUtil smsSendUtil0 = _smsSendUtilMock.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil0);




            _smsSendUtilMock2.Setup(e => e.GetSpName()).Returns("平台B");




            _smsSendUtilMock2.SetupSequence(e => e.SendSms(It.IsAny<SmsMessageResult>()))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now.AddDays(-2) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now.AddDays(-2) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now.AddDays(-2) }))


                .Returns(Task.Run<SmsMessageResult>(() => new SmsMessageResult() { Result = "1", Content = "222222", Mobile = "14500000000", SendObjIndex = 1, SendObjIndexList = new List<int> { 0 }, Time = DateTime.Now.AddDays(-2) }));


            ISmsSendUtil smsSendUtil2 = _smsSendUtilMock2.Object;


            smsSendBusiness.AddSendUtil(smsSendUtil2);




            #endregion




            for (var i = 0; i < 20; i++)


            {


                smsSendBusiness.DoLoop();


            }




            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendSuccessNum, 0);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendSuccessNum, 2);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[0].SendFailNum<3, true);


            Assert.AreEqual(smsSendBusiness.ListSmsSendUtilExt[1].SendFailNum, 0);


        }


    }


}