如何使用 Monodevelopment 上的 Moq 框架模拟读取 C# 文件的文本输出

本文关键字:文件 文本 输出 读取 模拟 Monodevelopment 何使用 上的 Moq 框架 | 更新日期: 2023-09-27 18:36:31

我整个周末都在为此努力。基本上,我正在为游戏生活做一个代码kata,它涉及阅读文本文件。我接收了包含网格二维表示的文本文件,并将所有点存储在列表列表中。我试图将从文件获得的文本输入模拟为"'"一行新行,以便我可以编写单元测试,检查列表列表中是否正在创建一个新列表。我创建了一个文件包装器来处理文本文件的读取,这就是我试图模拟的。代码符合要求,但测试失败,并显示错误消息"System.ArgumentException:指定的路径不是合法形式"。它似乎仍然期待文件路径,但模拟应该改变这种行为,对吗?任何帮助将不胜感激。


using System.Collections.Generic;
namespace GameOfLife
{
    public class InitializeGrid
    {
        public InitializeGrid ()
        {
        }
        public List<List<char>> CreateCharMatrix (string filePathName)
        {
            // Reads in the text file containing the grid data
            FileWrapper fileWrapper = new FileWrapper ();
            string inputGridTextFile = fileWrapper.ReadTextFromFile (filePathName);
            // Creates character matrix and initialises the first sub List
            List<List<char>> charMatrix = new List<List<char>> ();
            charMatrix.Add(new List<char>());
            int rowIndex = 0;
            int colIndex = 0;
            foreach (char cell in inputGridTextFile) {
                if (cell == ''n') {
                    charMatrix.Add (new List<char> ());
                    rowIndex++;
                    colIndex = 0;
                } else {
                    charMatrix [rowIndex] [colIndex] = cell;
                    colIndex++;
                }
            }
            return charMatrix;
        }
    }
}

using NUnit.Framework;
using System;
using System.Collections.Generic;
using Moq;
namespace GameOfLife
    [TestFixture()]
    public class InitializeGridTest
    {
        [Test()]
        public void CreateCharMatrix_EnsuresThatWhenEndOfLineReachedNewSubListCreated()
        {
            //Arrange
            InitializeGrid initializeGrid = new InitializeGrid ();
            List<List<char>> charMatrix;
            string filePathName = " ";
            Mock<IFileWrapper> mockFileWrapper = new Mock<IFileWrapper> ();
            mockFileWrapper.Setup<string> (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("'n");
            mockFileWrapper.Setup (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("'n");
            //Act
            charMatrix = initializeGrid.CreateCharMatrix (filePathName);
            int countProvingAnAdditionalListHasBeenAdded = charMatrix.Count;
            //Assert
            Assert.AreEqual (2, countProvingAnAdditionalListHasBeenAdded);
        }
    }

using System;
using System.IO;
namespace GameOfLife
{
    public class FileWrapper : IFileWrapper
    {
        public string ReadTextFromFile(string path)
        {
            return File.ReadAllText (path);
        }
    }
}

using System;
namespace GameOfLife
{
    public interface IFileWrapper
    {
        string ReadTextFromFile(string filePathName);
    }
} 

如何使用 Monodevelopment 上的 Moq 框架模拟读取 C# 文件的文本输出

查看您的代码,InitializeGrid 仍在使用 FileWrapper 类。它没有使用模拟类,因此代码仍在尝试使用文件系统。

类需要使用 IFileWrapper 接口,而不是 FileWrapper 类。我会考虑将 IFileWrapper 接口传递到 InitializeGrid 类的构造函数中。

public class InitializeGrid
{
    IFileWrapper fileWrapper;
    public InitializeGrid (IFileWrapper fileWrapper)
    {
        this.fileWrapper = fileWrapper;
    }
    public List<List<char>> CreateCharMatrix (string filePathName)
    {
        string inputGridTextFile = fileWrapper.ReadTextFromFile (filePathName);
        // More code here...
    }
}

在测试中,您将使用模拟的 IFileWrapper 构造 InitializeGrid 对象,方法是将 mockFileWrapper.Object 传递给其构造函数。

        List<List<char>> charMatrix;
        string filePathName = " ";
        Mock<IFileWrapper> mockFileWrapper = new Mock<IFileWrapper> ();
        mockFileWrapper.Setup<string> (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("'n");
        mockFileWrapper.Setup (m => m.ReadTextFromFile (It.IsAny<string>())).Returns ("'n");
        InitializeGrid initializeGrid = new InitializeGrid (mockFileWrapper.Object);