嗨,我正在研究C#应用程序。我正在为控制器级别编写单元测试用例。下面是我的控制器代码。
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++;
}
}
}
下面是我的单元测试用例。
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);
}
每当我在单元测试用例上运行时,控制就会进入Product product = new Product(productEvent,log);我想嘲笑这一行。我可以知道如何处理这种情况吗?任何帮助,将不胜感激。谢谢
答案 0 :(得分:0)
至少有两种方法。
最可取的:添加第二种方法,该方法允许您注入所需的元素。您可以从另一方法中调用一种方法以重用代码。第二种方法将用于测试。另一个应保持原样。
另一个选择是使用一个框架,该框架允许实施垫片以进行测试。例如: -Moles,“允许用委托替换任何.NET方法”。在这里,您可以看到一个允许模拟DateTime构造函数的示例:Nikolai Tillmann: Moles - Replace any .NET method with a delegate。 -“ Microsot假货”:Isolating Code Under Test with Microsoft Fakes。 -有些商业测试框架也支持垫片。
但是,您应该使用第一个提出的解决方案,或者更改软件的设计,例如使用“依赖注入”,以便可以轻松地在单元测试中控制依赖关系。在没有其他选择的情况下,应使用垫片,例如,将更改注入第三方库中,而您不能选择修改其代码。
您可以在Google“ .NET填充测试”中了解有关此技术的更多信息。