NUnit:代码的写单元测试需要使用物理文件

时间:2013-02-03 13:16:29

标签: c# unit-testing nunit

我最近开始使用NUnit框架为我的代码编写单元测试。
我熟悉NUnit的基本概念并编写简单的测试。
实际上我不知道如何测试使用文件的代码: 例如,我想为下面的类编写测试:

  public class ShapeLoader
    {
        private static void StreamLoading(object sender, StreamLoadingEventArgs e)
        {
            try
            {
                string fileName = Path.GetFileName(e.AlternateStreamName);
                string directory = Path.GetDirectoryName(e.AlternateStreamName);

                e.AlternateStream = File.Exists(directory + @"\\" + fileName) ? new FileStream(directory + @"\\" + fileName, e.FileMode, e.FileAccess) : null;
            }
            catch
            { }
        }

        public static ShapeFileFeatureLayer Load(string filePath, ShapeFileReadWriteMode shapeFileReadWriteMode, bool buildIndex = true)
        {
            if (!File.Exists(filePath)) { throw new FileNotFoundException(); }
            try
            {
                switch (shapeFileReadWriteMode)
                {
                    case ShapeFileReadWriteMode.ReadOnly:
                        //  if (buildIndex && !HasIdColumn(filePath)) BuildRecordIdColumn(filePath, BuildRecordIdMode.Rebuild);

                        ShapeFileFeatureLayer.BuildIndexFile(filePath, BuildIndexMode.DoNotRebuild);

                        var shapeFileLayer = new ShapeFileFeatureLayer(filePath, shapeFileReadWriteMode) { RequireIndex = true };
                        ((ShapeFileFeatureSource)shapeFileLayer.FeatureSource).StreamLoading += StreamLoading;
                        return shapeFileLayer;

                    case ShapeFileReadWriteMode.ReadWrite:
                        return new ShapeFileFeatureLayer(filePath, shapeFileReadWriteMode);

                    default:
                        return null;
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Could not find file")) throw new FileNotFoundException();
                throw;
            }
        }
    }

此代码需要物理文件来检查它是否正常工作,但单元测试与物理文件的依赖关系是否正确?
如何为这样的代码编写单元测试?

3 个答案:

答案 0 :(得分:3)

单元测试不应与外部资源(如文件系统或数据库等)有任何依赖关系。 在这种情况下,您必须使用模拟框架,例如 Moq Rhino Mock 。 如果要测试代码及其外部依赖项,则应编写Integration Test

所以在你的情况下,如果你不想使用任何模拟框架,你可以为依赖项创建自己的假类并通过依赖注入模式

传递它们

答案 1 :(得分:1)

我喜欢创造这个:

public abstract class FileSystem
{
     public abstract bool FileExists(string fullPath);
     public abstract Stream OpenFile(string fullPath, FileMode mode, FileAccess access);
}

然后,您可以以明显的方式为生产代码实现它,并轻松地为测试代码进行模拟。

[Test]
public void StreamReadingEventAddsStreamToEventArgsWhenFileExists()
{
     var e new StreamReadingEventArgs { e.AlternateStreamName= "Random string in path format", e.FileMode = AnyFileMode(), e.FileAccess = AnyFileAccess() };
     var expectedStream = new MemoryStream();
     _fileSystemMock.Setup(f=>f.OpenFile(e.AlternateStreamName, e.FileMode, e.FileAccess)).Returns(expectedStream);

     SomehowFireTheEvent(e);

     Assert.That(e.AlternateStream, Is.SameAs(expectedStream));
}

作为旁注,此代码还有其他可测试性问题会让您感到沮丧。我建议尝试为它编写一些测试,然后在codereview.stackexchange.com上发布生产代码和测试以获得一些反馈。

答案 2 :(得分:1)

无论您使用何种依赖项或使用外部资源,都要为每个资源创建模拟,然后使用模拟框架(如MOQ)运行测试。这是一个例子。更好地创建界面并使用界面

实现模拟
  var mockEmailRequest = new Mock<IEMailRequest>
  mockEmailResponse.setup(x+>x.EmailResponse).Returns(.....);
mockEmailRequest.Verify(r=>r.EmailReceived(It.Is<EmailResponse>(r=>r.Subject == "Something"),It.Is<int>(i=>i > 17)));