系列目錄 <https://www.cnblogs.com/tylerzhou/p/11204826.html>
我們前面說過.Moq在創(chuàng)建模擬對象的時(shí)候,簡單對象賦值默認(rèn)值,引用對象賦值為null,但是有些時(shí)候接口里面還包含另一個(gè)接口對象,我們知道Moq是可以模擬一個(gè)接口對象的,我們可以通過配置讓Moq模擬所有可以Mock的對象.
我們新增如下代碼
public interface IDtoWrapper { MyDto Dto { get; set; } string GetString(); }
public interface IOutString { IDtoWrapper wrapper { get; set; } }
比如我們要模擬一個(gè)IOutString對象,如果不使用默認(rèn)的行為則里面的wrapper對象返回為Null,如果這樣我們沒法再繼續(xù)操作了.
我們可以對Moq的Default行為進(jìn)行配置,讓它對IDtoWrapper對象也進(jìn)行Mock
測試代碼如下
[Test] public void BehaviorConfig() { var moq = new Mock<IOutString>();
moq.DefaultValue = DefaultValue.Mock; Assert.NotNull(moq.Object.wrapper); }
以上測試會(huì)通過.這時(shí)候wrapper不再是null,我們便可以對其進(jìn)行操作了.
我們通過調(diào)試可以發(fā)現(xiàn)這時(shí)候不但I(xiàn)DtoWrapper不再是null,它里面的Dto屬性也被賦值為一個(gè)new
MyDto.是不是Mock框架可以模擬一個(gè)對象呢,實(shí)際上確實(shí)是可以,只不過是它模擬對象有很多限制,比如不能模擬不包含無參構(gòu)造函數(shù)的對象,不能模擬不帶virtual或者abstract的方法等.如果我們對模擬的對象的方法沒有virual或者abstract修飾,這時(shí)候如果進(jìn)行setup則會(huì)拋出異常.
前面我們講的如何通過配置使mock自動(dòng)mock遇到到層級可Mock對象.這一節(jié)我們來看另一個(gè)問題.
假如有這樣一種場:要mock的接口里有一個(gè)Name屬性,在業(yè)務(wù)層我們要根據(jù)這個(gè)Name決定進(jìn)入switch的不同分支里面,但是回顧前面的章節(jié),我們沒有遇到這種情況,我們都是只是在mock對象建立時(shí)使用setup為要mock的對象的字段設(shè)置值.很多人可能會(huì)想,可以通過moq對象實(shí)體的Object屬性把這個(gè)對象拿出來,然后改變它的值.我們來看看這樣做可行不可行.
我們有以下一個(gè)簡單接口
public interface ISt { string Name { get; set; } int Age { get; set; } }
測試方法如下
[Test] public void BehaviorConfig() { var moq = new Mock<ISt>(); var obj =
moq.Object; obj.Name = "baidu"; Assert.NotNull(moq.Object.Name); }
我們把moq的Object對象賦值給obj,然后通過obj改變Name值.我們斷言moq.Object.Name的值不為null,不幸的是,測試沒有通過.
按我們理解obj和moq.Object應(yīng)該是引用類型,所以obj值的改變會(huì)引起moq.object值的改變,然而實(shí)際情況卻是我們一旦把moq.Objectm賦值給了obj,它們之間便脫離了關(guān)系.看來這樣是行不通的.
如何解決這個(gè)問題呢,其實(shí)moq實(shí)例對象里面有一個(gè)SetupProperty方法,我們可以通過它來顯示指定哪些屬性會(huì)被跟蹤,如果屬性被跟蹤,則它的變化就會(huì)被記錄下來,而不像上面.
[Test] public void BehaviorConfig() { var moq = new Mock<ISt>();
moq.SetupProperty(a => a.Name); var obj = moq.Object; obj.Name = "baidu";
Assert.NotNull(moq.Object.Name); }
我們多加了一行代碼,測試便可以通過了.
但是如果屬性很多,這樣一行一行幾乎重復(fù)的代碼挺煩的,moq實(shí)例里面還有一個(gè)SetupAllProperties
方法,這樣可以設(shè)置所有的屬性都被跟蹤.這樣如果多條需要這個(gè)值,我們便不需要每次都mock它,而只需要給它重新賦值即可.
熱門工具 換一換