1

我的应用程序是一个.NET Core应用程序。

我有一个public如下所示的方法,它有两个私有方法。

   public bool CallService(JObject requestJsonObj, out Status status)
   {
        bool provisioningSuccess = false;
        var preProcessSuccess = PreProcessing(requestJsonObj,out Status status);
        var postProcessSuccess = PostProcessing(requestJsonObj,out Status status);

        if(preProcessSuccess && postProcessSuccess)
        {
              status = Status.ProvisionSuccess;
              provisioningSuccess = true;
        }
        return provisioningSuccess;
   }

这是状态和私人课程

   public enum Status
   {
       [Description("User/Pwd not valid")]
       CredentialInvalid = 111,
       [Description("Provision is success")]
       ProvisionSuccess = 112,
   }

    private PreProcessing(JObject JosnObj, 
        out Status status)
    {
           using (var client = new HttpClient())
           {
                var request = new {.........};
                var response = client.PostAsJsonAsync("api/preprocess", request).Result;
           }
    }

    private PostProcessing(JObject JosnObj, 
        out Status status)
    {
            //..... 
    }

尝试了以下方法,

     PrivateObject privateHelperObject = new PrivateObject(typeof(MainService));
     actual = (bool)privateHelperObject.Invoke("CallService", requestJsonObj,status);    

它说

找不到类型或命名空间名称“PrivateObject”(您是否缺少 using 指令或程序集引用?)

这是一个 .NET CORE 项目。我不确定是否PrivateObject支持.net core?

4

3 回答 3

5

您首先不需要PrivateObject,因为您要测试的成员是public

var target = new MainService();
var actual = target.CallService(requestJsonObj, status);

您的方法本身调用私有方法并不会改变您测试该方法的方式public

如果你真的需要测试私有的,事情会变得更难。所以让我们使用反射,这PrivateObject在引擎盖下也是如此。

var mainServiceObject = new MainService();
var method = mainService.GetType().GetMethod("PreProcessing", BindingFlags.Instance | BindingFlags.NonPublic);

var result = (bool) method.Invoke(mainServiceObject, new[] { requestJsonObj, status });

但是请注意,对私有成员进行单元测试通常被认为是代码异味,并且通常表明设计存在问题 - 即您的类做得太多,应该分成多个类,每个类都有一个单一的职责。

于 2020-01-10T09:35:20.950 回答
3

首先,当您需要在单元测试中测试私有方法时,这种情况很少见。通常你测试一个单元 - 一个调用所有其他私有(或不)方法的公共方法。但确实有时私有方法内部的逻辑太多,或者方法是不直接调用的事件/消息处理程序。

其次,正如已经提到的,PrivateObject它不是 .NET Core/Standard 的一部分,我认为它永远不会是。

作为一种解决方法,您可以使用反射在单元测试中调用私有方法:

var mainServiceObject = new MainService();
var method = typeof(MainService).GetMethod("PrivateMethod", BindingFlags.Instance | BindingFlags.NonPublic);
var result = method?.Invoke(mainServiceObject, new object[] { requestJsonObj, status });

附言

请注意,在您的代码CallService中是公共方法,因此无需通过反射调用它。

于 2020-01-10T09:38:17.277 回答
2
var mainService = new MainService(); // This is only to visualise that you need to pass an instance of the class


var dynMethod = typeof(MainService).GetMethod("PreProcessing", BindingFlags.NonPublic | BindingFlags.Instance);

dynMethod.Invoke(mainService , new object[] { methodParams });

// methodParams 应该是这个方法接受的参数

于 2020-01-10T09:37:51.437 回答