首页 > 解决方案 > 当单元测试实例化类时,实例化类中的图像会触发 System.IO 异常

问题描述

我有一个可以正常工作的 Windows 窗体应用程序(编译在 bin\debug 中创建 .exe 以及一个名为“Images”的文件夹。这个“Images”文件夹位于我的项目解决方案文件夹中,并设置为“始终复制”。

编译代码后,一切正常,没有 System.IO 异常。

但是,如果引用图像的类是在没有编译和通过单元测试工具的情况下实例化的,我会看到以下内容:

System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement) at System.Drawing.Image.FromFile(String filename) at YahtzeeApplication.GameBoard..ctor() in E:\workspaces\visual studio projects\Yahtzee\YahtzeeApplication\YahtzeeApplication \GameBoard.cs:第 124 行 UnitTestProject.GameBoardTest.GameBoardElements() 中 E:\workspaces\visual studio projects\Yahtzee\YahtzeeApplication\UnitTestProject\GameBoardTest.cs:第 37 行结果消息:System.IO.FileNotFoundException:Images\1。骰子.GIF

这是加载图像的代码:

diceImageArray[0] = Image.FromFile("Images\\1.dice.GIF");

我正在查看测试类或实例化类是否没有看到图像。但是当我将一个名为“Images”的文件夹放在相对于调用的任一位置时,错误并没有消失。

你在单元测试中为这个场景做了什么?

标签: c#visual-studiounit-testingnunit

解决方案


相对路径不正确,因为您无法控制当前目录,这是相对路径所基于的。如果您只是运行控制台应用程序而不首先更改到包含图像目录的目录,则相同的代码也会失败,例如...

foo\bar\myprogram.exe

通常,程序的用户可以控制当前目录。程序更改当前目录或依赖它被设置到任何特定位置是不好的形式......就像正在运行的程序集的位置。

查找图像目录的替代方法取决于路径是在您的测试中还是在被测应用程序中确定的。如果它在测试中,则 NUnit 具有TestContext.TestDirectory,它是包含测试程序集的目录的路径。如果它在应用程序本身中,则需要以某种方式对应用程序进行编码,以找到相对于某个特定位置的图像目录,例如包含主程序的目录。如果您指出此代码的位置,那么我可以给出更准确的建议。

更新 - 2019 年 1 月 22 日

在应用程序中使用相对路径是应用程序的一个弱点,这将导致它在某些情况下失败,除非您在程序运行时完全控制当前目录设置。在 NUnit 下运行测试只是其中一种情况。IMO,您应该更改应用程序,以便它在相对于包含 exe 的目录而不是相对于当前目录的路径中找到图像。这需要更多的代码,但更好,因为这实际上是您打算发生的事情。通过指出这个问题,您的测试正在帮您一个忙!

这里有一些代码可以相对于加载图像的程序集的位置来定位图像(见下面的异常)......

string assemblyPath = GetType().Assembly.Location;
string assemblyDir = Path.GetDirectory(assemblyPath);
string imagePath = path.Combine(assemblyDir, "Images\\1.dice.GIF");
diceImageArray[0] = Image.FromFile(imagePath);

我将代码分布在多行中,以便您可以更轻松地查看每个步骤。当然,您可以组合其中的一些。该代码仅在 SO 中“编译”,因此我将留下任何错误供您修复。:-)

上述代码的例外情况是您的代码正在被影子复制。然后,您需要访问它来自的原始位置,而不是当前位置。如果发生这种情况,则需要更多代码,我不想使示例过于复杂。

如果加载图像的程序集总是相对于自身定位它们,那么只要您确保图像存在于该位置,您的测试就应该工作。


推荐阅读