【问题标题】:Mocking service method that requires two streams to be open at the same time需要同时打开两个流的模拟服务方法
【发布时间】:2015-04-24 22:13:29
【问题描述】:

我正在尝试 Moq 一种需要 2 个流的方法。即:StreamReader 和 StreamWriter。但是,当我运行测试时,我似乎无法通过编译器抛出的异常。每次运行测试时,我都会遇到 System.IO.IOException,因为蒸汽正被另一个进程使用。

public void LoadStockLevels(string reportId)
{
    //read file line by line
    CreateRequiredFiles(reportId);
    _updateItemList = new List<IStockLevelItem>();
    _updateAttributeItemList = new List<AttributeItem>();

    try
    {
        _sr = _streamReaderWrapper.GetStreamReader(_report + reportId + ".xml");
        while ((_line = _sr.ReadLine()) != null)
        {
            //sync stock levels
            var stockItem = _line.Split('\t');
            if (stockItem[0] != "sku")
            {
                _updateItemList.Add(new StockLevelItem()
                {
                    Identifier = stockItem[1],
                    Sku = stockItem[0],
                    Quantity = stockItem[3]
                });
                _updateAttributeItemList.Add(new AttributeItem()
                {
                    AttributeValue = stockItem[1],
                    AttributeKey = "IDENT"
                });
            }
            else
            {
                _wsr = _streamWriterWrapper.GetStreamWriter(_inventoryFile, true);
                _wsr.WriteLine(
                    "sku    price   minimum-seller-allowed-price    maximum-seller-allowed-price    quantity    leadtime-to-ship");
                _wsr.Close();
            }
        }
        _sr.Close();
    }
    catch (Exception ex)
    {
        if(_sr != null) _sr.Close();
        if (_wsr != null) _wsr.Close();
        _log.Error("Failed to load stock levels", ex);
    }
}

单元测试:

[Test]
public void Test_LoadStockLevels_CatchesException()
{
    using (var stream1 = new MemoryStream())
    {
        using (var bmp1 = new Bitmap(1, 1))
        {
            var graphics1 = Graphics.FromImage(bmp1);
            graphics1.FillRectangle(Brushes.Black, 0, 0, 1, 1);
            bmp1.Save(stream1, ImageFormat.Jpeg);
        }
        _streamWriterWrapper.Setup(s => s.GetStreamWriter(It.IsAny<string>(), It.IsAny<bool>()))
        .Returns(new StreamWriter(stream1.ToString(), true));

    }

    using (var stream2 = new MemoryStream())
    {
        using (var bmp2 = new Bitmap(1, 1))
        {
            var graphics2 = Graphics.FromImage(bmp2);
            graphics2.FillRectangle(Brushes.Black, 0, 0, 1, 1);
            bmp2.Save(stream2, ImageFormat.Jpeg);
        }
        _streamReaderWrapper.Setup(s => s.GetStreamReader(It.IsAny<string>()))
            .Returns(new StreamReader(stream2.ToString()));
        // Assert something with postedFile here 
        _stockSyncService = new StockSyncService(_stockSync.Object, _tService.Object, _features.Object,
            _macduffClient.Object, _configManager.Object, _streamReaderWrapper.Object, _streamWriterWrapper.Object);
        var result = _stockSyncService.LoadStockLevels("504978");
        Assert.IsInstanceOf<StreamWriter>(result);
    }
}

我知道模拟流的问题已经得到解答,但我不确定这个问题是否被问过。

是否可以模拟一个需要使用 2 个流和一个内存流的测试。

/** 编辑:添加 StackTrace **/

Test 'StockIntergration.Services.Tests.StockSync.StockSyncServiceTests.Test_LoadStockLevels_CatchesException' failed:
    System.IO.IOException : The process cannot access the file 'C:\Users\ianrichards\Documents\Repositories\StockIntergration\StockIntergration.Services.Tests\bin\Debug\System.IO.MemoryStream' because it is being used by another process.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
    at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
    at System.IO.StreamReader..ctor(String path)
    StockSync\StockSyncServiceTests.cs(199,0): at StockIntergration.Services.Tests.StockSync.StockSyncServiceTests.Test_LoadStockLevels_CatchesException()

0 passed, 1 failed, 0 skipped, took 3.71 seconds (NUnit 2.6.2).

【问题讨论】:

  • 这个new StreamWriter(stream1.ToString(), true)) 代码应该做什么?
  • 请同时添加完整的消息(还有几行堆栈跟踪)。

标签: c# .net nunit moq


【解决方案1】:

不使用就试试这个测试。处理流可能存在问题。删除 usings 并在测试结束时手动关闭和处置流。

【讨论】:

    【解决方案2】:

    以下代码是罪魁祸首:

         new StreamWriter(stream1.ToString(), true))
    

    ToString 在大多数类上返回类名,这正是异常所显示的 - new StreamReader("MemoryStream", true) 尝试在当前文件夹中创建具有给定名称的文件并失败。

    您正在寻找在第一个字节数组上创建另一个 MemoryStream:

    new StreamWriter(new MemoryStream(stream1.ToArray(), false)));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-03
      • 1970-01-01
      相关资源
      最近更新 更多