[英]How to mock StreamReader in NUnit
我正在嘗試使用 NUnit 和 Moq 為我的示例項目編寫單元測試。 我有如下服務 class:
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.