C#-使用Guid参数引发事件的单元测试方法

如何解决C#-使用Guid参数引发事件的单元测试方法

我正在尝试弄清楚如何测试这种情况,并且空白。

我有一个侦听器服务,当在邮槽中检测到文件时,它将触发以下内容

IEventdispatcher _dispatcher;
IListener _mailslotListener;

public Service (IEventdispatcher dispatcher,ImailslotListener mailslotListener) {
  _dispatcher = dispatcher;
  _mailslotListener = mailslotListener;
}

public async void _Listener_OnFileDetected(object sender,mailslotArgs) {
  string filePath = args.Message;

  Directory.CreateDirectory(TempLocation);

  FileId = Guid.NewGuid();
  string tempPath = Path.Combine(TempLocation,FileId.ToString());
    
  File.Move(filePath,tempPath);

  await _dispatcher.dispatchEvent("documentPrinted",FileId);
}

这会将传入的文件移动到临时位置,并使用Guid重命名。在测试中,我试图验证文件是否已成功移动,但不确定如何访问已使用并传递给_dispatcher.dispatchEvent调用的Guid。

我能够验证是否引发了该事件,但是就我得到的结果而言,当在测试中断言相等时,作为随机Guid的值似乎是一个问题。

[Test]
public void OnFileDetected_CallsdispatchEvent()
{
  Directory.CreateDirectory(tempPath);
  listenerService._Listener_OnFileDetected(null,new mailslotArgs(testFilePath));

  mockEventdispatcher.Verify(m => m.dispatchEvent("fileDetected",It.IsAny<Guid>()),Times.Once);
}

解决方法

这是static初始化程序的典型问题。它是众所周知的DateTime.Now变体,但结果是相同的。

问题在于,由于它具有静态特性,因此很难模拟该方法的输出。

由于在实现中使用了它,因此GUID的结果将保留在其中,并且没有简单的方法可以访问它。

一种常见的方法是创建一个包装类+接口,以公开Guid.NewGuid()方法。

使用这种方法,您可以完全控制Guid一代-您只需要使用适当的类即可。

//The interface
public interface IGuidGenerator
{
     Guid NewGuid();
}

//Use in the application
public class GuidGenerator: IGuidGenerator
{
    public Guid NewGuid()
    {
        return Guid.NewGuid();
    }
}

//Use in the test scenario
public class TestGuidGenerator: IGuidGenerator
{
    public Guid NewGuid()
    {
        return new Guid("dddddddd-dddd-dddd-dddd-dddddddddddd");
    }
}

如果使用的是IoC框架,只需注册接口和类,然后将生成器传递给服务即可。

public Service (IEventDispatcher dispatcher,IMailslotListener mailslotListener,IGuidGenerator guidGenerator) 
{
   _dispatcher = dispatcher;
   _mailslotListener = mailslotListener;
   _guidGenerator = guidGenerator;
}

DateTime.Now变体实际上通常用作面试问题。 以下是有关此主题的更多信息:https://dvoituron.com/2020/01/22/UnitTest-DateTime/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?