diff --git a/MoqStudy.MockModel/DemoModel/CallBaseHelper.cs b/MoqStudy.MockModel/DemoModel/CallBaseHelper.cs
new file mode 100644
index 0000000..8465d10
--- /dev/null
+++ b/MoqStudy.MockModel/DemoModel/CallBaseHelper.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MoqStudy.MockModel
+{
+ public class CallBaseHelper
+ {
+ ///
+ /// 获取当前时间
+ ///
+ public virtual string NameFormat(string name)
+ {
+ return name.ToUpper();
+ }
+ }
+}
diff --git a/MoqStudy.MockModel/MoqStudy.MockModel.csproj b/MoqStudy.MockModel/MoqStudy.MockModel.csproj
index 2d0e6a9..9258221 100644
--- a/MoqStudy.MockModel/MoqStudy.MockModel.csproj
+++ b/MoqStudy.MockModel/MoqStudy.MockModel.csproj
@@ -45,6 +45,7 @@
+
diff --git a/MoqStudy.Test/MoqDemoTest.cs b/MoqStudy.Test/MoqDemoTest.cs
index 34517f2..a0e6166 100644
--- a/MoqStudy.Test/MoqDemoTest.cs
+++ b/MoqStudy.Test/MoqDemoTest.cs
@@ -427,31 +427,46 @@ namespace MoqStudy.Test
}
///
- /// 期望(等同于检查),属性已经被设置为指定的值
- /// 用法暂不明确:可以用VerifySet替代本功能
+ /// 期望属性被赋值为指定的值
+ /// 可由VerifySet替代
///
[Fact]
public void Property_SetupSet_Test()
{
- mock //todo:用法不明确,待查
+ mock //期望属性被赋值为指定的值
//可以使用 VerifySet 替代
- .SetupSet(foo => foo.Name = "foo");
+ .SetupSet(foo => foo.Name = "ping")
+ //使设置可以验证,如果没有此设置,则SetupSet设置,无从知道SetupSet设置的效果
+ .Verifiable();
+ //属性值不为指定的值时,验证时异常
+ Assert.Throws(()=>mock.Verify());
- Assert.Equal(1,2);
+ //属性值赋值为指定值时,验证通过
+ //或者 加上 mock.Setup(f => f.Name).Returns("ping");
+ ifoo.Name = "ping";
+ mock.Verify();
}
///
- /// 验证设置属性
- /// 用法暂不明确:可以用VerifySet替代本功能
+ /// 验证属性读取
///
[Fact]
public void Property_SetupGet_Test()
{
- mock //todo:用法不明确,待查
- .SetupGet(foo => foo.Name);
-
- Assert.True(1==2);
+ mock //期望属性值被读取
+ //可以使用 VerifyGet 替代
+ .SetupGet(foo => foo.Name)
+ //使设置可以验证,如果没有此设置,则SetupGet设置,无从知道SetupSet设置的效果
+ .Verifiable();
+
+ //属性值未被读取时,验证时异常
+ Assert.Throws(() => mock.Verify());
+
+ //属性值被读取时,验证通过
+ //或者加上 mock.Setup(f => f.Name).Returns("ping");
+ var getName = ifoo.Name;
+ mock.Verify();
}
///
@@ -792,8 +807,6 @@ namespace MoqStudy.Test
[Fact]
public void Verify_AtLeastOnce_Test()
{
- var mock = new Mock();
- var ifoo = mock.Object;
MockException mockException = null;
var customInfo = "custom info";
try
@@ -832,8 +845,6 @@ namespace MoqStudy.Test
[Fact]
public void Verify_Propertie_Get_Test()
{
- var mock = new Mock();
- var ifoo = mock.Object;
MockException mockException = null;
var customInfo = "custom info";
try
@@ -855,7 +866,7 @@ namespace MoqStudy.Test
try
{
//读取1次属性
- var rr = ifoo.Name;
+ var getName = ifoo.Name;
mock.VerifyGet(foo => foo.Name, customInfo);
mockException = null;
}
@@ -874,8 +885,6 @@ namespace MoqStudy.Test
[Fact]
public void Verify_Propertie_Set_Test()
{
- var mock = new Mock();
- var ifoo = mock.Object;
MockException mockException = null;
var customInfo = "custom info";
try
@@ -987,7 +996,6 @@ namespace MoqStudy.Test
#region 定制模拟行为
///
- /// Customizing Mock Behavior
/// 定制Mock模式
/// 默认模式,等同宽松模式:未设置的Mock行为或属性保持默认值或默认行为
/// 严格模式:未设置的Mock行为或属性,不可使用(异常)
@@ -1000,7 +1008,6 @@ namespace MoqStudy.Test
Assert.Null(looseOrDefaultMock.Object.Name);
Assert.False(looseOrDefaultMock.Object.Add(1));
-
//严格模式
var strictMock = new Mock(MockBehavior.Strict);
@@ -1009,27 +1016,40 @@ namespace MoqStudy.Test
}
///
- /// Callbase
- /// 使用Callbase
- /// 如果没有重写基类的实现,默认将不会调用基类,在 Mock Web/Html 控件的是必须的
- /// http://www.360doc.com/content/14/0729/09/10504424_397815601.shtml
+ /// 使用Callbase,调用真实对象的实际方法或属性
///
[Fact]
public void CustomMock_Callbase_Test()
{
- /*
- Invoke base class implementation if no expectation overrides the member
- (a.k.a. "Partial Mocks" in Rhino Mocks): default is false.
- (this is required if you are mocking Web/Html controls in System.Web!)
- */
- //如果没有重写基类的实现,默认将不会调用基类,在 Mock Web/Html 控件的是必须的。
- var mock = new Mock { CallBase = true };
-
- //todo:需要验证
+ var mock = new Mock { CallBase = true };
+ var actual = mock.Object;
+
+ mock //参数长度大于5,调用真实代码,返回参数的大写形式
+ .Setup(m => m.NameFormat(It.Is(f => f.Length > 5)))
+ .CallBase();
+
+ mock //参数长度小于等于5,模拟返回值,返回参数的小写形式
+ .Setup(m => m.NameFormat(It.Is(f => f.Length <= 5)))
+ .Returns(arg=>arg.ToLower());
+
+ var length3 = "AbC";
+ var length4 = "Abcd";
+ var length5 = "aBced";
+
+ var length6 = "Acccde";
+ var length10 = "aBcdefghig";
+
+ Assert.Equal(length3.ToLower(), actual.NameFormat(length3));
+ Assert.Equal(length4.ToLower(), actual.NameFormat(length4));
+ Assert.Equal(length5.ToLower(), actual.NameFormat(length5));
+
+ Assert.Equal(length6.ToUpper(), actual.NameFormat(length6));
+ Assert.Equal(length10.ToUpper(), actual.NameFormat(length10));
}
///
- /// 创造自动递归的Mock, Mock 对象对于它的任何成员将会返回一个新的 Mock 对象。
+ /// 创造自动递归的Mock
+ /// Mock对象对于它的任何成员将会返回一个新的 Mock 对象。
///
[Fact]
public void CustomMock_Automatic_Test()
@@ -1052,20 +1072,28 @@ namespace MoqStudy.Test
}
///
- /// 中心化的 Mock 实例创建和管理:你可以在一个地方使用 MockRepository 创建和验证所有的 Mock 对象,设置 MockBehavior, CallBse 和 DefaultValue 约束。
+ /// 中心化的 Mock 实例创建和管理
+ /// 你可以在一个地方使用 MockRepository 创建和验证所有的 Mock 对象,设置 MockBehavior, CallBse 和 DefaultValue 约束。
///
[Fact]
public void CustomMock_MockRepository_Test()
{
- var repository = new MockRepository(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };
+ var repository = new MockRepository(MockBehavior.Strict)
+ {
+ DefaultValue = DefaultValue.Mock,
+ CallBase = false,
+ };
// Create a mock using the repository settings
+ // 使用中心化设置创建 Mock 对象
var fooMock = repository.Create();
// Create a mock overriding the repository settings
+ // 创建覆盖中心化设置的 Mock 对象
var barMock = repository.Create(MockBehavior.Loose);
// Verify all verifiable expectations on all mocks created through the repository
+ // 验证
try
{
repository.Verify();
@@ -1076,8 +1104,6 @@ namespace MoqStudy.Test
Assert.Null(ex);
}
}
-
-
#endregion
#region 其它