我有一个包含成员的界面,如下所示:
public interface IDataLoader
{
//other stuff
// tools for loading the items to be processed from disk or cloud
CustomCollection ItemsToBeProcessed {get; set;}
}
我正在为消耗那些ItemsToBeProcessed
的系统其他组件做UT,我想避免加载的复杂性和依赖性。
在每个UT中,我都想用特定的硬编码数据填充ItemsToBeProcessed。然后将数据馈送到要测试的模块(处理器模块),并将输出与特定的硬编码预期数据进行比较。
我的问题是我无法初始化此ItemsToBeProcessed
,但我不明白为什么。
到目前为止,这是我的UT:
[Test]
public void DataProcessor_TestData1_asExpected()
{
Mock<IDataLoader> mokedAmplifier = new Mock<IDataLoader>(MockBehavior.Loose);
MainController.Loader = mokedAmplifier.Object;
if(MainController.Loader.ItemsToBeProcessed == null)
MainController.Loader.ItemsToBeProcessed = new CustomCollection();
// here the MainController.Loader.ItemsToBeProcessed is still null.. why???
var TestData = LoadTestData("testData1.xml");
var ExpectedData = LoadExpectedData("ExpectedData1.xml")
MainConroller.Loader.ItemsToBeProcessed.AddRange(TestData);
var ProcessingModuleBeingTested = new ProcessingModule();
var results = ProcessingModuleBeingTested.Process(MainController.Loader.ItemsToBeProcessed);
Asert.isEqual(ExepctedData, results);
}
我如何初始化此成员?
答案 0 :(得分:3)
模拟所需的成员以在调用时返回可用的对象。
var collection = new CustomCollection();
var mokedAmplifier = new Mock<IDataLoader>(MockBehavior.Loose);
mokedAmplifier.Setup(_ => _.ItemsToBeProcessed).Returns(collection);
//...
如果您希望模拟对象记住对属性所做的更改,请使用SetupAllProperties
指定模拟中的所有属性都应具有“属性行为”, 这意味着设置其值将导致将其保存并稍后返回 当请求属性时。 (也称为“存根”)。默认值 每个属性的值将是由 模拟的Moq.Mock.DefaultValue属性。
var mokedAmplifier = new Mock<IDataLoader>(MockBehavior.Loose);
mokedAmplifier.SetupAllProperties(); //<--
MainController.Loader = mokedAmplifier.Object;
if(MainController.Loader.ItemsToBeProcessed == null)
MainController.Loader.ItemsToBeProcessed = new CustomCollection();
//...
参考Moq Quickstart,以帮助您理解模拟框架。
答案 1 :(得分:2)
属性只不过是一种get方法和set方法。如果要为模拟实例分配值,则只需使用 setter 方法,该方法与getter方法无关。。因此,由thefault Mock为您创建一个类似于以下内容的类:
class TheMockClass : IDataLoader
{
CustomCollection get_ItemsToBeProcessed { return whatever; }
void set_ItemsToBeProcessed { }
}
如果您为此类的实例分配某些内容,则不会发生任何事情,因为setter绝对不会做任何事情(不确定具体的内部原理,但重要的是,即使setter做了任何事情,也与它无关。在吸气剂中使用。
您看到,当被模拟时,这两种方法没有任何共同之处。因此,您必须同步进行模拟。但是,通常只需模拟 getter 即可返回您的值,因为您只是使用被模拟的值,而不是设置。
mokedAmplifier.Setup(_ => _.ItemsToBeProcessed).Returns(new CustomCollection());
答案 2 :(得分:1)
您需要设置属性:
mokedAmplifier.SetupAllProperties();
MainController.Loader = mokedAmplifier.Object;
if (MainController.Loader.ItemsToBeProcessed == null)
MainController.Loader.ItemsToBeProcessed = new CustomCollection();
或
var coll = new CustomCollection();
mokedAmplifier.Setup(x => x.ItemsToBeProcessed).Returns(coll);