5
public class Business {  
    protected List<BusinessRulesDto> BusinessRules { get; set; }  
}

我试过了:

  1. businessMockObject.Protected().SetupSet<List<BusinessRulesDto>>("BusinessRules", ItExpr.IsAny<List<BusinessRulesDto>>()).Verifiable();
    
  2. var businessRulesDtoList = Builder<BusinessRulesDto>.CreateListOfSize(2).Build().ToList();  
    businessMockObject.Protected().SetupGet<List<BusinessRulesDto>>("BusinessRules").Returns(businessRulesDtoList);
    businessMockObject.Protected().SetupSet<List<BusinessRulesDto>>("BusinessRules", ItExpr.IsAny<List<BusinessRulesDto>>()).Verifiable();
    

我尝试了很多东西,但都没有成功。我能够模拟受保护的方法,但不能模拟受保护的属性。

如何模拟受保护的属性?

4

2 回答 2

3

根据文档

Moq 4.8 及更高版本允许您通过具有相同成员的完全不相关的类型设置受保护的成员,从而提供 IntelliSense 工作所需的类型信息。您还可以使用此接口设置受保护的泛型方法和具有 by-ref 参数的方法:

在测试项目中创建一个接口来封装被mock的protected成员

public interface IBusinessProtectedMembers {  
    List<BusinessRulesDto> BusinessRules { get; set; }  
}

然后将其与模拟一起使用以利用 IntelliSense

var businessRulesDtoList = Builder<BusinessRulesDto>.CreateListOfSize(2).Build().ToList();
businessMockObject.Protected().As<IBusinessProtectedMembers>()
    .Setup(_ => _.BusinessRules)
    .Returns(businessRulesDtoList);

最后,这一切都取决于 Moq 的要求,即要模拟/存根的成员必须是虚拟的,以便允许框架覆盖成员。

这意味着Business应该看起来像

public class Business {  
    protected virtual List<BusinessRulesDto> BusinessRules { get; set; }  
}

为使上述建议起作用。

于 2018-03-28T10:55:02.797 回答
1

引擎盖下的模拟创建目标的子类。每当目标是具体类(不是接口)时,您要模拟的方法应该是虚拟的,否则子类无法覆盖它并提供Setupped功能。

于 2018-03-28T06:20:43.860 回答