How to mock an SqlDataReader using Moq - Update

后端 未结 5 1418
温柔的废话
温柔的废话 2021-01-30 17:12

I\'m new to moq and setting up mocks so i could do with a little help. How do I mock up an SqlDataReader using Moq?

Update

After further testing this is what I h

5条回答
  •  闹比i
    闹比i (楼主)
    2021-01-30 17:42

    Moq has an ability to run some code after the method is executed. It is called "Callback". Modify your code this way and it will work:

    private IDataReader MockIDataReader()
    {
        var moq = new Mock();
    
        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;
    }
    

    But what if it will be required IDataReader to contain not only single row, but several? Well, here is a sample:

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

提交回复
热议问题