Попытка подделать службу данных, которая возвращает IDataReader - PullRequest
1 голос
/ 04 ноября 2011

Я пытаюсь смоделировать (используя Rhino.Mocks) DataService, который возвращает IDataReader.Я могу издеваться над IDataReader ( StackOverFlow Q 1792984 ), но если я затем заглушу Службу данных, которая возвращает этот DataReader и внедряет его в метод, который я пытаюсь проверить, то заглушка возвращает только нулевое Читатель данных.

IDataService

public interface IDataService
{
 SqlDataReader ExecuteReader(string cmdText, CommandType commandType);
 <rest of definition ommited
}

Модульный тест

    [TestMethod]
    public void GetCustomer_Pass()
    {
        //Arrange
        var customer = new Customer()
                       {
                         Id = 1, FirstName = "Patrick",
                         LastName = "Hastings", ProfilePictureURL = ""
                       };

        var mockDataService = MockRepository.GenerateStub<IDataService>();

        var reader = MockRepository.GenerateStub<IDataReader>();
        reader.Stub(x => x.Read()).Repeat.Once().Return(true);
        reader.Stub(x => x.Read()).Return(false);
        reader.Stub(x => x["Id"]).Return(customer.Id);
        reader.Stub(x => x["FirstName"]).Return(customer.FirstName);
        reader.Stub(x => x["LastName"]).Return(customer.LastName);
        reader.Stub(x => x["ProfilePictureURL"]).Return(customer.ProfilePictureURL);

        mockDataService.Stub( s =>
            s.ExecuteReader(string.Format("select FirstName, LastName,ProfilePictureURL from customer where Id = {0}", customer.Id),
                            CommandType.Text))
                            .Return(reader as SqlDataReader);

        var custRepository = new CustomerRepository(mockDataService);

        //Act
        var customer2 = custRepository.GetCustomer(1);
        //Assert
        Assert.AreEqual(customer.FirstName, customer2.FirstName,"FirstName Mismatch");
        Assert.AreEqual(customer.LastName, customer2.LastName, "LastName Mismatch");
    }

Метод UnderTest

    public CustomerRepository(IDataService dataService) //Constructor
    {
        if (dataService == null) throw new ArgumentNullException("dataService", "dataService cannot be null.");
        this.dataService = dataService;
    }

    public Customer GetCustomer(int id)
    {
        var sql =string.Format("select FirstName, LastName, ProfilePictureURL from customer where Id = {0}",id);
        var dr = dataService.ExecuteReader(sql, CommandType.Text);
        Customer customer ;
        using (dr)
        {
            if (!dr.Read()){return null;}
            customer = new Customer
                         {
                             FirstName = dr["FirstName"].ToString(),
                             LastName = dr["LastName"].ToString(),
                             ProfilePictureURL = dr["ProfilePictureURL"].ToString()
                         };
        }
        return customer;
    }

Эта проблема возникает, когда "dataService.ExecuteReader(sql, CommandType.Text); "должен вернуть поддельный IDataReader, но вместо этого возвращает Null - любые указания относительно того, что я делаю неправильно, будут с благодарностью оценены.

1 Ответ

1 голос
/ 04 ноября 2011

Первая точка:

Я полагаю, что из-за различных аргументов, передаваемых в метод ExecuteReader ():

Установить в ожидании:

"select FirstName, LastName,ProfilePictureURL...

Пройдено во время фактического вызова: (дополнительный пробел между запятой и ProfilePictureURL)

"select FirstName, LastName, ProfilePictureURL...

Иногда IgnoreArguments() очень полезно, когда сам аргумент не имеет значения

Второй пункт:

.Return(reader as SqlDataReader);

Это недопустимое приведение, потому что читатель - фиктивный объект, созданный RhinoMock.

Полагаю, вам не нужен тип SqlDataReader, поэтому просто верните сам читатель

 .Return(reader)

PS: Также я бы предложил хранить значения, которые повторяются как константы, вы также можете хранить customerId = 1 как константы, чтобы избежать таких возможных проблем.

...