Как дразнить использование SqlDataReader Moq - Обновление

Я плохо знаком с moq и настраивающими насмешками, таким образом, я мог сделать с небольшой справкой. Как я копирую использование SqlDataReader Moq?

Обновление

После дальнейшего тестирования это - то, что я имею до сих пор:

private IDataReader MockIDataReader()
{
    var moq = new Mock();
    moq.Setup( x => x.Read() ).Returns( true );
    moq.Setup( x => x.Read() ).Returns( false );
    moq.SetupGet( x => x["Char"] ).Returns( 'C' );

    return moq.Object;
}

private class TestData
{
    public char ValidChar { get; set; }
}

private TestData GetTestData()
{
   var testData = new TestData();

   using ( var reader = MockIDataReader() )
   {
       while ( reader.Read() )
       {
           testData = new TestData
           {
               ValidChar = reader.GetChar( "Char" ).Value
           };
       }
   }

   return testData;
}

Проблема Вы - когда я делаю читателя. Прочитайте в моем GetTestData () метод его всегда пустой. Я должен знать, как сделать что-то как

reader.Stub( x => x.Read() ).Repeat.Once().Return( true ) 

согласно носорогу дразнят пример: Насмешка DataReader и получение Носорога. Насмешки. Исключения. ExpectationViolationException: IDisposable. Расположите (); Ожидаемый № 0, Фактический № 1

36
задан Community 23 May 2017 в 11:54
поделиться

2 ответа

Moq может запускать некоторый код после выполнения метода. Это называется «Обратный звонок». Измените свой код таким образом, и он будет работать:

private IDataReader MockIDataReader()
{
    var moq = new Mock<IDataReader>();

    bool readToggle = true;

    moq.Setup(x => x.Read())
         // Returns value of local variable 'readToggle' (note that 
         // you must use lambda and not just .Returns(readToggle) 
         // because it will not be lazy initialized then)
        .Returns(() => readToggle) 
        // After 'Read()' is executed - we change 'readToggle' value 
        // so it will return false on next calls of 'Read()'
        .Callback(() => readToggle = false); 

    moq.Setup(x => x["Char"])
        .Returns('C');

    return moq.Object;
}

private class TestData
{
    public char ValidChar { get; set; }
}

private TestData GetTestData()
{
    var testData = new TestData();

    using ( var reader = MockIDataReader() )
    {
       testData = new TestData
       {
           ValidChar = (Char)reader["Char"]
       };
   }

   return testData;
}

Но что, если потребуется, чтобы IDataReader содержал не только одну строку, а несколько? Вот пример:

// You should pass here a list of test items, their data
// will be returned by IDataReader
private IDataReader MockIDataReader(List<TestData> ojectsToEmulate)
{
    var moq = new Mock<IDataReader>();

    // This var stores current position in 'ojectsToEmulate' list
    int count = -1;

    moq.Setup(x => x.Read())
        // Return 'True' while list still has an item
        .Returns(() => count < ojectsToEmulate.Count - 1)
        // Go to next position
        .Callback(() => count++);

    moq.Setup(x => x["Char"])
        // Again, use lazy initialization via lambda expression
        .Returns(() => ojectsToEmulate[count].ValidChar);

    return moq.Object;
}
61
ответ дан 27 November 2019 в 05:39
поделиться

После некоторого тестирования проблема заключается в попытке установить для DataReader.Read () значение true для один цикл, а затем установив его в false. В Rhino Mock есть опция Repeat.Once (), но я не смог найти аналогичный метод в Moq (здесь я могу ошибаться).

Основной причиной тестирования этого метода были методы расширения для преобразования считывателя в соответствующий тип данных, поэтому в конце я удалил цикл while и просто получил доступ к значениям, которые были установлены в моем макете. Код выглядит следующим образом:

private IDataReader MockIDataReader()
{
    var moq = new Mock<IDataReader>();
    moq.SetupGet<object>( x => x["Char"] ).Returns( 'C' );

    return moq.Object;
}

private class TestData
{
    public char ValidChar { get; set; }
}

private TestData GetTestData()
{
    var testData = new TestData();

    using ( var reader = MockIDataReader() )
    {
       testData = new TestData
       {
           ValidChar = reader.GetChar( "Char" ).Value
       };
   }

   return testData;
}

Не идеальное решение, но работает. Если кто знает, лучше оставьте комментарий, спасибо.

1
ответ дан 27 November 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: