diff --git a/MoqStudy.MockModel/DemoModel/DemoHelper.cs b/MoqStudy.MockModel/DemoModel/DemoHelper.cs new file mode 100644 index 0000000..c8a1c66 --- /dev/null +++ b/MoqStudy.MockModel/DemoModel/DemoHelper.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MoqStudy.MockModel +{ + public class DemoHelper + { + } + + public interface CommandBaseProtectedMembers + { + bool Execute(string arg); + } + + public interface TeacherDoubling + { + decimal Doubling(decimal number); + } +} diff --git a/MoqStudy.MockModel/MoqStudy.MockModel.csproj b/MoqStudy.MockModel/MoqStudy.MockModel.csproj index 9258221..6b3a3a4 100644 --- a/MoqStudy.MockModel/MoqStudy.MockModel.csproj +++ b/MoqStudy.MockModel/MoqStudy.MockModel.csproj @@ -46,6 +46,7 @@ + diff --git a/MoqStudy.MockModel/StudyModel/Teacher.cs b/MoqStudy.MockModel/StudyModel/Teacher.cs index 3f20a57..b53baa9 100644 --- a/MoqStudy.MockModel/StudyModel/Teacher.cs +++ b/MoqStudy.MockModel/StudyModel/Teacher.cs @@ -23,9 +23,9 @@ namespace MoqStudy.MockModel return Id + GroupId; } - protected virtual int GetAge(int age) + protected virtual decimal Doubling(decimal number) { - return age + 2; + return number * 2; } protected virtual bool Execute(int number) @@ -36,5 +36,13 @@ namespace MoqStudy.MockModel } return number % 2 == 0; } + + /// + /// 运行私有方法 + /// + public virtual bool CompareWithDoubling(decimal number) + { + return number > Doubling(number); + } } } diff --git a/MoqStudy.Test/MoqDemoTest.cs b/MoqStudy.Test/MoqDemoTest.cs index a0e6166..bcfd928 100644 --- a/MoqStudy.Test/MoqDemoTest.cs +++ b/MoqStudy.Test/MoqDemoTest.cs @@ -1138,25 +1138,73 @@ namespace MoqStudy.Test [Fact] public void Miscellaneous_Protected_Test() { - //todo:用法还不清楚 - var mock = new Mock(); + var mock = new Mock() { CallBase = true }; + var protectValue = 5; mock.Protected() - .Setup("GetAge",2) - .Returns(5); - //todo:设置好了,怎么使用是个问题 + .Setup("Doubling", It.IsAny()) + .Returns(protectValue); - // if you need argument matching, - // you MUST use ItExpr rather than It planning on improving this for vNext - // (see below for an alternative in Moq 4.8) + // 如果用到了参数匹配, 必须使用 ItExpr 来代替 It + // 以后计划改进 mock.Protected() .Setup("Execute", ItExpr.IsAny()) .Returns(true); + + //注意使用方法: + //设置模拟对象的保护成员后,直接访问不了(保护级别限制) + // 使用验证方法进行验证,或者在其它设置里直接使用保护方式的变量结果。 + mock.Setup(t => t.CompareWithDoubling(It.IsAny())) + .Returns((decimal p)=> { return p > protectValue; }); + + var runValue1 = mock.Object.CompareWithDoubling(1); + var runValue3 = mock.Object.CompareWithDoubling(3); + var runValue5 = mock.Object.CompareWithDoubling(5); + + var runValue7 = mock.Object.CompareWithDoubling(7); + + Assert.False(runValue1); + Assert.False(runValue3); + Assert.False(runValue5); + Assert.True(runValue7); + } + + /// + /// 接口方式,设置保护成员 + /// 4.8及更高版本 + /// + [Fact] + public void Miscellaneous_Protected_UseInterface_Test() + { + var mock = new Mock() { CallBase = true }; + var protectValue = 5; + mock //保护方法转为接口,进行设置 + .Protected() + .As() + .Setup(m=>m.Doubling(It.IsAny())) + .Returns(protectValue); + + //注意使用方法: + //设置模拟对象的保护成员后,直接访问不了(保护级别限制) + // 使用验证方法进行验证,或者在其它设置里直接使用保护方式的变量结果。 + mock.Setup(t => t.CompareWithDoubling(It.IsAny())) + .Returns((decimal p) => { return p > protectValue; }); + + var runValue1 = mock.Object.CompareWithDoubling(1); + var runValue3 = mock.Object.CompareWithDoubling(3); + var runValue5 = mock.Object.CompareWithDoubling(5); + + var runValue7 = mock.Object.CompareWithDoubling(7); + + Assert.False(runValue1); + Assert.False(runValue3); + Assert.False(runValue5); + Assert.True(runValue7); } #endregion #region 高级特性 [Fact] - public void Advanced_GetFromMocked_Test() + public void Advanced_GetMockFromMocked_Test() { // get mock from a mocked instance IFoo foo =new Mock().Object; // get mock instance somehow 以某种方式获取模拟实例