簡體   English   中英

如何在 NUnit 中模擬 StreamReader

[英]How to mock StreamReader in NUnit

我正在嘗試使用 NUnit 和 Moq 為我的示例項目編寫單元測試。 我有如下服務 class:

情感服務.cs:

public class SentimentService : ISentimentService
{
    private readonly IStreamReader _reader;
    private readonly IServerClient _serverClient;

    public SentimentService(IStreamReader reader, IServerClient serverClient)
    {
        _reader = reader;
        _serverClient = serverClient;
    }


    public async Task<string> CalculateSentimentFromTextFile(IFormFile file)
    {
        var input = "";
        using (StreamReader streamReader = _reader.GetReader(file.OpenReadStream()))
        {
            input = streamReader.ReadToEnd();
            streamReader.Close();
        }

        var result = await _serverClient.PostAsync<SentimentResult, string>($"submit_string", input);

        return result.label;
    }
}

我試過像下面這樣使用最小起訂量:

[Test]
public async Task CalculateSentimentFromTextFileEquality()
{
    var mockFormFile = new Mock<IFormFile>();
    var mockStreamReader = new Mock<IStreamReader>();
    var mockServerClient = new Mock<IServerClient>();

    var mockResult = new SentimentResult
    {
        label = "Positive"
    };

    mockStreamReader.Setup(o => o.GetReader(mockFormFile.Object.OpenReadStream()));

    mockServerClient.Setup(o => o.PostAsync<SentimentResult, string>(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(mockResult);

    var sut = new SentimentService(mockStreamReader.Object, mockServerClient.Object);
    var result = await sut.CalculateSentimentFromTextFile(mockFormFile.Object);

    Assert.That(result, Is.EqualTo("Positive"));
}

但是,出現以下錯誤:

在此處輸入圖像描述

這個設置:

 mockStreamReader.Setup(o => o.GetReader(mockFormFile.Object.OpenReadStream()));

不返回任何 object,因此在 SUT 中調用它時:

StreamReader streamReader = _reader.GetReader(file.OpenReadStream()

將返回 null object。

然而, StreamReader參數的構造函數,這意味着如果你想模擬它,你必須提供真實的文件路徑/流。 處理StreamReader的一種方法是創建一個接口,稍后可以由StreamReader的包裝器實現。

public interface IStreamReader : IDisposable
{
    string ReadToEnd();
    void Close();
}

IStreamReader的創建由工廠完成:

public interface IStreamReaderFactory
{
    IStreamReader GetReader(Stream stream);
}

您的 SUT 可以修改為:

public class SentimentService : ISentimentService
{
    private readonly IStreamReaderFactory _readerFactory;
    private readonly IServerClient _serverClient;

    public SentimentService(IStreamReaderFactory readerFactory, IServerClient serverClient)
    {
        _readerFactory = readerFactory;
        _serverClient = serverClient;
    }


    public async Task<string> CalculateSentimentFromTextFile(IFormFile file)
    {
         var input = "";
         using (IStreamReader streamReader = _readerFactory.GetReader(file.OpenReadStream()))
         {
             input = streamReader.ReadToEnd();
             streamReader.Close();
         }

         var result = await _serverClient.PostAsync<SentimentResult, string>($"submit_string", input);

         return result.label;
    }
}

測試代碼現在應該能夠正確設置IStreamReader

var mockStreamReader = new Mock<IStreamReader>();
var mockStreamReaderFactory = new Mock<IStreamReaderFactory>();

mockStreamReaderFactory.Setup(o => o.GetReader(It.IsAny<Stream>())).Returns(mockStreamReader.Object);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM