简体   繁体   English

在单元测试案例中,从物理路径读取csv文件是否有效? 为什么?

[英]Is reading csv file from physical path is valid scenario in unit test case ? why?

string _inboundFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\Inbound\CompareDataFile.csv";

var mockReaderStream = new Mock<IReaderStream>();
mockReaderStream.Setup(x => x.CreateStream())
    .Returns(new System.IO.StreamReader(_inboundFilePath));

Here I am dependent on an inbound file to read data from and then perform other function checks. 在这里,我依赖于入站文件来读取数据,然后执行其他功能检查。 my question is how to avoid this? 我的问题是如何避免这种情况? In this case I am checking data for a particular id that comes in from the csv. 在这种情况下,我正在检查数据以获取来自csv的特定ID。

It is not likely to be a good practice because a unit test must be deterministic. 因为单元测试必须是确定性的,所以这不太可能是一个好习惯。 It means that whatever the situation, you must be sure that if this test runs, it will do exactly the same than before. 这意味着无论情况如何,您都必须确保如果运行此测试,它将执行与以前完全相同的操作。

If you read a csv file, the test will depend on the external world. 如果您读取一个csv文件,则测试将取决于外部环境。 And unfortunately, the external world is not stable. 不幸的是,外部世界是不稳定的。 For a start somebody can change the csv file. 首先,可以更改csv文件。

That is why it is a better practice to get the csv file stream from a an embedded resource in the assembly instead of getting it from a file on the hard drive. 这就是为什么更好的做法是从程序集中的嵌入式资源获取csv文件流,而不是从硬盘驱动器上的文件获取csv文件流。

In addition to the answer from Stephane. 除了斯蒂芬的答案。 I will suggest you: 我会建议你:

  1. Put @"\\Inbound\\CompareDataFile.csv" to config file. 将@“ \\ Inbound \\ CompareDataFile.csv”放入配置文件。

  2. Create public property or separate method in the aforementioned class that will be able to retrieve and return the inbound file absolute path (call it GetPath ). 在上述类中创建公共属性或单独的方法,这些方法将能够检索并返回入站文件的绝对路径(称为GetPath )。

  3. Create UnitTest method that have access to the config file. 创建有权访问配置文件的UnitTest方法。 This TestMethod must read config files, call AppDomain.CurrentDomain.BaseDirectory . 此TestMethod必须读取配置文件,并调用AppDomain.CurrentDomain.BaseDirectory So this method could also retrieve the path of inbound file absolute path and after this call GetPath() 因此,此方法还可以检索入站文件的绝对路径,并在此调用之后获取GetPath()

  4. Create abstraction (interface or abstract class above Mock - (it's not a mock by the way in the code you've provided, so hard to guess why you call it so)). 创建抽象(Mock上方的接口或抽象类-(在您提供的代码中它不是模拟的,因此很难猜测为什么如此称呼))。

  5. Create public method in the aforementioned class that will require an object of the abstraction and call its method ReadFromCsv() . 在上述类中创建需要抽象对象的公共方法,并调用其方法ReadFromCsv()

  6. Create Test class (mock) that will implement this abstraction and will return desired/undesired values when you call it's method ReadFromCsv() . 创建将实现此抽象的Test类(模拟),并在调用其方法ReadFromCsv()时返回所需/不想要的值。

  7. Finally, test your class. 最后,测试您的课程。

PS. PS。 This is not a strict algorithm of testing the class, you can use it. 这不是测试类的严格算法,可以使用它。 By what you would like to get from all this seven items is the notion of unit-test-likeness. 您希望从所有这七个项目中得到的是单元测试相似性的概念。

Also you do not free your class from config file, so, use this approach to free your class from config: How to mock ConfigurationManager.AppSettings with moq 同样,您也不会从配置文件中释放类,因此,请使用这种方法从配置中释放类: 如何使用moq模拟ConfigurationManager.AppSettings

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

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