1

怎么可能只调用一次委托方法/一次用痣?

MyClass.AllInstances.ResultateGet = delegate { return new ResultatInfoCollection(); };

我只想调用一次“ResultateGet”方法,因为第一次没有委托的情况下,init 非常复杂。

target.UpdateResultate(); //calls delegate "ResultateGet"
//Assert some stuff
target.Verify(); //needs original function "ResultateGet" so unit test is useful

我通常对如何在调用原始函数而不是委托之前调用一次或特定次数的痣代表感兴趣。

更新: 我找到了一种方法,这似乎有点麻烦。有更好的解决方案吗?

ResultatInfoCollection x = new ResultatInfoCollection();
MolesContext.ExecuteWithoutMoles(() => x = target.Resultate);
4

2 回答 2

2

另外,请参阅我对以下内容的回答:How to assign/opt from multiple delegates for a 'moled' method? 这提供了匿名方法内部的门控逻辑示例。

哦,好问题!我自己也遇到过这种情况。您正在寻找的称为“失败”行为(执行原始代码)。Moles 绕道而行的匿名方法必须包含一个切换机制,在第一次调用之后就会失败。不幸的是,目前我不相信 Moles 中包含失败功能。

您更新的解决方法正是您所需要的——调用 fallthrough 会做同样的事情。我建议添加一个标记值doFallthrough来控制调用:

bool doFallthrough = false;
ResultatInfoCollection x = new ResultatInfoCollection();
MyClass.AllInstances.ResultateGet = delegate { 
    if (!doFallthrough)
    {
        doFallthrough = true;
        return new ResultatInfoCollection();
    }
    MolesContext.ExecuteWithoutMoles(() => x = target.Resultate);
};

调用特定次数只需要更改哨兵值类型:

int doFallthrough = 0;
ResultatInfoCollection x = new ResultatInfoCollection();
MyClass.AllInstances.ResultateGet = delegate { 
    if (++doFallthrough < 5)
        return new ResultatInfoCollection();
    MolesContext.ExecuteWithoutMoles(() => x = target.Resultate);
};
于 2011-08-04T22:34:59.957 回答
0

老问题,但由于我在搜索时找到了它,我会用我的解决方案为下一个人回答它。

在大多数情况下,使用MolesContext.ExecuteWithoutMoles调用原始函数可以正常工作,但是,如果您在此调用的下游添加任何其他函数或类,它们也不会被添加。

给定以下课程:

public class TheClass
{
    public int TheFunction(int input){
        return input + TheOtherFunction();
    }

    public int TheOtherFunction(){
        return DateTime.Now.Minutes;
    }
}

如果您使用该MolesContext.ExecuteWithoutMoles方法:

MTheClass.AllInstances.TheOtherFunctionInt = (instance) => {
    return 5;
};

MTheClass.AllInstances.TheFunctionInt = (instance, input) =>
{
    //do your stuff here, for example:
    Debug.WriteLine(input.ToString());

    var result = MolesContext.ExecuteWithoutMoles<int>(() => instance.TheFunction(input));

    //do more stuff, if desired    
    return result;
};

您的 OtherFunction 的痣不会被击中,因为它是在“无痣”范围内(间接)执行的。

但是,您可以随时添加和删除 moles 代表,以便您执行以下操作,如Moles 文档(p. 24)中所述

MTheClass.AllInstances.TheOtherFunctionInt = (instance) => {
    return 5;
};

MolesDelegates.Func<TheClass, int, int> molesDelegate = null;
molesDelegate = (instance, input) =>
{
    //do your stuff here, for example:
    Debug.WriteLine(input.ToString());

    int result = 0;
    try{
        MTheClass.AllInstances.TheFunctionInt = null;
        result = instance.TheFunction(input);
    }
    finally{
        MTheClass.AllInstances.TheFunctionInt = molesDelegate;
    }

    //do more stuff, if desired

    return result;
};

MTheClass.AllInstances.TheFunctionInt = molesDelegate;

OtherFunction 痣仍然被击中。使用这种方法,您可以仅从特定方法中去除痣,而不会影响其他痣。我用过这个,它有效。我能看到的唯一麻烦是,如果你有递归函数,或者可能是多线程情况,它就不起作用。

于 2013-11-08T17:22:09.130 回答