简体   繁体   English

如何在C#xUnit测试用例中模拟构造函数?

[英]How to mock constructor in c# xUnit test case?

Hi I am working on C# application. 嗨,我正在研究C#应用程序。 I am writing unit test case for controller level. 我正在为控制器级别编写单元测试用例。 Below is my controller code. 下面是我的控制器代码。

 public IActionResult TriggerProductEventCheck([FromQuery(Name = "timeout-secs")] int timeoutS = 120)
    {
      int productEventsCount = 0;
      if (productService.ProcessingEnabled)
      {
        var cts = new CancellationTokenSource();
        cts.CancelAfter(timeoutS * 1000);
        lock (SyncObject)
        {
          this.consumerClient.Subscribe(this.productEventTopicName);
          while (!cts.IsCancellationRequested)
          {
            var productEvent = this.eventDispatcher.Consume();
            long kafkaOffSet = productEvent.Offset.Value;
            Product product = new Product(productEvent, log);
            if (product.Options == null)
            {
              break;
            }

            if (product != null)
            {
              productService.ProcessProductEvents(product, kafkaOffSet);
            }

            productEventsCount++;
          }
        }
      }

Below is my unit test case. 以下是我的单元测试用例。

 public void ShouldReturnIfNoSQSEvents()
      {
        var productEventController = MockProvider.Target<ProductEventController>();
        productEventController.GetDependency<IProductEventService>().ProcessingEnabled.Returns(true);

        productEventController.GetDependency<IEventDispatcher>().Consume().Returns(new Confluent.Kafka.ConsumeResult<string, Avro.Generic.GenericRecord>());

        productEventController.GetDependency<IConsumerClient>().Subscribe("test");
        var productclass = Substitute.For<Product>();
        var response = productEventController.Target.TriggerProductEventCheck() as JsonResult;
        ((int)response.StatusCode).ShouldBe(200);
      }

Whenever I run above unit test case, Control goes inside Product product = new Product(productEvent, log); 每当我在单元测试用例上运行时,Control就会进入Product product = new Product(productEvent,log); I want to mock this particular line. 我想嘲笑这一行。 May I know how to handle this condition? 我可以知道如何处理这种情况吗? Any help would be appreciated. 任何帮助,将不胜感激。 Thanks 谢谢

There are at least two ways. 至少有两种方法。

The most advisable: add a second method that allows you to inject the desired elements. 最建议:添加第二种方法,该方法允许您注入所需的元素。 You can call one method from the other to reuse code. 您可以从另一方法中调用一种方法以重用代码。 This second method would be used for testing. 第二种方法将用于测试。 The other shuld be left as is. 另一个应保持原样。

Another option is to use a framework that allows to implement shims for testing. 另一种选择是使用一个框架,该框架允许实施垫片以进行测试。 For example: - Moles , that "allows to replace any .NET method with a delegate". 例如: -Moles ,“允许用委托替换任何.NET方法”。 Here you can see an example that allows to mock DateTime constructor: Nikolai Tillmann: Moles - Replace any .NET method with a delegate . 在这里,您可以看到一个允许模拟DateTime构造函数的示例: Nikolai Tillmann:Moles-将所有.NET方法替换为委托 - "Microsot fakes": Isolating Code Under Test with Microsoft Fakes . -“ Microsot假货”: 使用Microsoft Fakes 隔离测试中的代码 - There are some commercial testing frameworks that also support shims. -有些商业测试框架也支持垫片。

However, you should use the first proposed solution, or change the desing of your software, for example using Dependency Injection, so that you can easily control de dependencies in your unit testing. 但是,您应该使用第一个提出的解决方案,或者更改软件的设计,例如使用“依赖注入”,以便可以轻松地在单元测试中控制依赖关系。 You should leave the use of shims for cases where you don't have any other option, for example injecting changes in third party libraries for which you don't have the option to modify their code. 在没有其他选择的情况下,应使用垫片,例如,在您没有选择修改其代码的第三方库中注入更改。

You can google ".NET shims testing" to learn more about this technique. 您可以在Google“ .NET填充测试”中了解有关此技术的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM