提问者:小点点

使用FakeItEasy模拟私有方法


我已经实现了使用FakeItEasy Framework模拟测试公共虚拟方法的解决方案。下面我有一个带有Private方法的Test类,而Private方法不能是虚拟的。所以请帮我使用FakeItEasy Framework模拟Private方法

类待测试

public class XYZ
{
    public static int nValue = 0;

    private  void AddInetegers()
    {
        int i = 3;

        int j = i * 100;
        int k = j * 30 / 100;

        Show(String.Format("Value Here {0}", k.ToString()));

        nValue = k;
    }

    public virtual void Show(string message)
    {
        MessageBox.Show(message);
    }
}

测试类

[TestMethod]
   public void Test_Using_FakeItEasy()
    {

        var instance = A.Fake<XYZ>();

        A.CallTo(() => instance.Show("Hello"));

        //A.CallTo(() => instance.AddInetegers(3)).CallsBaseMethod();

        A.CallTo(instance).Where(x => x.Method.Name.Contains("AddInetegers")).MustHaveHappened();


        Assert.AreEqual(90, XYZ.nValue);
    }

错误:

结果消息:测试方法PrjMSTest. Test.Test_Using_FakeItEasy抛出异常:FakeItEasy.OutectationException:

以下调用断言失败:
对假对象进行的任何调用。
其中x=


共1个答案

匿名用户

正如他们在评论中告诉你的,你不能轻易地测试私有方法,在绝大多数情况下,你可能不应该。
如果出于某种原因,你仍然想测试AddInetegers(),有一种“肮脏”的方法可以隐藏某种信息并测试你的方法。

首先,您必须将AddInetegers设为内部;它在您的程序集之外不可见,您将能够测试它。

然后找到你的XYZ类所属项目的Properties\AssemblyInfo. cs文件;假设你的项目名为MyProject,你的测试项目是MyProjectTest,你可以添加

using System.Runtime.CompilerServices;

到AssemblyInfo. cs的顶部和

[assembly: InternalsVisibleTo("MyProjectTests")]

到底部。这将使您的方法可测试。更多信息在这里或这里。

var CurrentInstance = new XYZ();
var PrivateObject= new PrivateObject(CurrentInstance);
PrivateObject.Invoke("AddInetegers");

Assert.AreEqual(90, XYZ.nValue);
  1. 重构和/或向遗留系统添加测试时,您可能还没有时间熟悉

有时测试私有功能是最安全的

你很匆忙,必须在此时此地做尽可能快的事情。从长远来看,你不想测试私有方法。但我要说的是,重构通常需要一些时间来解决设计问题。有时你必须在一周内发货。没关系:做快速和肮脏的事情,并使用摸索工具测试私有方法,如果这是你认为最快和最可靠的完成工作的方法。但要明白,从长远来看,你所做的不是最佳的,请考虑回到它(或者,如果它被遗忘了,但你后来看到它,修复它)。