简体   繁体   English

模拟StreamWriter(C#起订量)

[英]Mocking StreamWriter (C# Moq)

I am writing a method that will write to a text file. 我正在写一个将写入文本文件的方法。 I am still trying to wrap my head around Dependency Inversion. 我仍在努力围绕依赖反转。

The issue I appear to be having is with mocking StreamWriter. 我似乎遇到的问题是嘲笑StreamWriter。

Here is my test, I commented out one of the setup lines, as this is where my issue is. 这是我的测试,我注释掉了其中一条设置行,因为这是我的问题所在。

[Test]
    public void WriteToAutomationLog_FileDoesNotExist_CreateFile()
    {
        //arrange
        mockDirectoryWrapper.Setup(_ => _.Exists(It.IsAny<string>())).Returns(true);
        mockFileWrapper.Setup(_ => _.Exists(It.IsAny<string>())).Returns(false);
        mockFileWrapper.Setup(_ => _.CreateText(logFile.GetAutomationLogsPath() + fileName)).Verifiable();
        //mockFileWrapper.Setup(_ => _.CreateText(logFile.GetAutomationLogsPath() + fileName)).Returns(new StreamWriter(fileName)).Verifiable();

        //act
        logFile.WriteToAutomationLog(fileName, message);

        //assert
        mockFileWrapper.Verify(_ => _.CreateText(logFile.GetAutomationLogsPath() + fileName), Times.Exactly(1));
    }

Here is my method I am testing on 这是我正在测试的方法

public void WriteToAutomationLog(string fileName, string message)
    {
        //Ensure the automation logs path still exists.
        if (_directoryWrapper.Exists(automationLogsPath))
        {
            //Check if file exists
            if (_fileWrapper.Exists(automationLogsPath + fileName))
            {
                //Append to log file
                using (StreamWriter sw = _fileWrapper.AppendText(automationLogsPath + fileName))
                {

                }
            }
            else
            {
                //Create new file
                using (StreamWriter sw = _fileWrapper.CreateText(automationLogsPath + fileName))
                {
                    sw.Write(message);
                }
            }
        }
    }

I have wrappers for the Directory and File class. 我有目录和文件类的包装。 The issue I am having is when I call sw.Write(message), sw is null in my test. 我遇到的问题是当我调用sw.Write(message)时,测试中sw为null。 When I use the commented out line of code that returns a StreamWriter, I get an error saying access to the file is denied. 当我使用注释掉的代码行返回StreamWriter时,我收到一条错误消息,指出对文件的访问被拒绝。 However I do not want to actually read the file on the hard drive. 但是,我不想实际读取硬盘驱动器上的文件。 How can I go about mocking StreamWriter? 我该如何模拟StreamWriter?

On a side note, if I comment out sw.Write(message), my test passes. 附带一提,如果我注释掉sw.Write(message),则测试通过。 This issue came up when I added another test to test sw.Write, so when I added that code my old test broke (the one that I posted). 当我添加另一个测试以测试sw.Write时出现了这个问题,所以当我添加该代码时,我的旧测试坏了(我发布的那个)。

我最终将代码重构为使用File.WriteAllText和File.AppendText,因此不需要添加其他依赖项。

You need to create mock for StreamWriter and return it in your currently commented out line instead the actual StreamWriter. 您需要为StreamWriter创建模拟,并在当前注释掉的行中返回它,而不是实际的StreamWriter。

Then it won't access the file. 然后它将无法访问该文件。 You can just check that Write(string) method with given message was actually called on the StreamWriter mock. 您只需检查在StreamWriter模拟中实际调用了具有给定消息的Write(string)方法。

c# xUnit Moq It.IsAny<object> 没有像预期的那样嘲笑<div id="text_translate"><p>以下是一段代码(简单的 HTTP post 调用),我试图在 Azure 函数中模拟:</p><pre> await httpClient.PostAsync("https://url.com", await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json"));</pre><p> 请注意,httpClient.PostAsync() 函数有两个参数:URL 作为字符串,body 作为对象。</p><p> 现在,在我的测试中,我像这样模拟这个 POST 调用:</p><pre> httpClientMock.Setup(s =&gt; s.PostAsync(It.IsAny&lt;string&gt;(), It.IsAny&lt;object&gt;())).ReturnsAsync(mockedHttpResponse);</pre><p> 我期待await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json")不会被调用,因为我将它设置为与任何对象一起工作。但是,我的测试用例失败了例外:</p><blockquote><p> 在 System.IO.Path.Combine(String path1, String path2) 处发现 System.ArgumentNullException 消息“Value cannot be null. (Parameter 'path1')”</p></blockquote><p> 当我通过在测试中设置环境变量来提供正确的路径(即使是虚拟路径也不起作用)时,它就起作用了。 但这似乎不是正确的方法,因为单元测试旨在在各种机器上运行,并且每台机器的基本路径都不同。</p></div></object> - c# xUnit Moq It.IsAny<object> not mocking as expected

暂无
暂无

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

相关问题 C#模拟嘲笑<StreamWriter> - C# mocking Mock<StreamWriter> 使用Moq模拟C#计时器 - Mocking a C# timer with Moq 在c#中使用Moq进行模拟 - Mocking using Moq in c# C#Moq - 模拟行动 <T> 参数 - C# Moq - Mocking Action<T> parameter 在C#中使用Moq模拟服务 - Mocking a Service using Moq in C# 使用 C# Moq 模拟 ElasticSearch 客户端 - Mocking an ElasticSearch client using C# Moq 用Moq模拟C#中的Excel的Comment.Text() - Mocking Excel's Comment.Text() in c# with moq 使用C#/ Moq Framework使用输入参数模拟异步DbContext函数 - Mocking async DbContext functions with input parameter with C#/Moq Framework c#Mocking具有Moq的具体类的接口成员 - c# Mocking Interface members of a concrete class with Moq c# xUnit Moq It.IsAny<object> 没有像预期的那样嘲笑<div id="text_translate"><p>以下是一段代码(简单的 HTTP post 调用),我试图在 Azure 函数中模拟:</p><pre> await httpClient.PostAsync("https://url.com", await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json"));</pre><p> 请注意,httpClient.PostAsync() 函数有两个参数:URL 作为字符串,body 作为对象。</p><p> 现在,在我的测试中,我像这样模拟这个 POST 调用:</p><pre> httpClientMock.Setup(s =&gt; s.PostAsync(It.IsAny&lt;string&gt;(), It.IsAny&lt;object&gt;())).ReturnsAsync(mockedHttpResponse);</pre><p> 我期待await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json")不会被调用,因为我将它设置为与任何对象一起工作。但是,我的测试用例失败了例外:</p><blockquote><p> 在 System.IO.Path.Combine(String path1, String path2) 处发现 System.ArgumentNullException 消息“Value cannot be null. (Parameter 'path1')”</p></blockquote><p> 当我通过在测试中设置环境变量来提供正确的路径(即使是虚拟路径也不起作用)时,它就起作用了。 但这似乎不是正确的方法,因为单元测试旨在在各种机器上运行,并且每台机器的基本路径都不同。</p></div></object> - c# xUnit Moq It.IsAny<object> not mocking as expected
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM