Дразнить ITable, используя RhinoMocks для тестирования nunit - PullRequest
1 голос
/ 30 августа 2011

У меня есть интерфейс, по которому я запускаю запрос linq to sql:

public interface IMyDataContext : IDisposable
{
    ITable<MyTable> GetMyTable();
}

На этом интерфейсе я выполняю запрос linq:

var results = from table1 in _MyDataContext.GetMyTable() 
    group table1 by table1.Column1 into myGroup
    orderby myGroup.Count() descending 
    select new
    {
        Column1 = myGroup.Key,
        Count = myGroup.Count()
    };

Запрос выполняетсяхорошо.Я застрял во время написания модульных тестов.Как получить функцию GetMyTable (), возвращающую макет объекта с некоторыми поддельными данными, вокруг задачи здесь:

public class MockMyContextWrapper : IMyDataContext
{
        public void Dispose()
        {

        }

        public ITable<MyTable> GetMyTable()
        {
            var table = MockRepository.GenerateMock<ITable<MyTable>>();

            //todo: code to return something so that the linq query fired on this table works

            return table;
        }
 }

Ответы [ 3 ]

2 голосов
/ 30 августа 2011

Если я правильно понимаю вашу проблему, вы, вероятно, захотите создать макет IMyDataContext, а не создавать собственную реализацию только для теста.

В макете IMyDataContext вы можете настроить ожидания следующим образом:*

var dataContext = MockRepository.GenerateMock<IMyDataContext>();
var table = MockRepository.GenerateMock<ITable<MyTable>>();
dataContext.Expect(x => x.GetMyTable()).Return(table);

Вы также можете настроить ожидания на макете таблицы.В качестве альтернативы вы можете создать новый экземпляр класса, реализующий интерфейс ITable, заполнив этот экземпляр тестовыми данными в памяти.

0 голосов
/ 20 октября 2013

ITable содержит 3 различных интерфейса: IEnumerable, IQueryable и другие элементы в ITable. Поскольку все, что вы делаете, это запрашиваете таблицу, вы можете вместо этого использовать IQueryable и передавать ее в макет / заглушку:

 IQueryable<MyTable> testTable = new[]{new MyTable{…}, new MyTable{…}, …, new MyTable{…}}.AsQueryable();
 myMock.Stub(x => x.GetMyTable()).Return(testTable);

каждый new MyTable{…} будет представлять строку в таблице.

Если / когда вам нужен полный ITable интерфейс, например поскольку вы хотите добавить или удалить строки из таблицы, вы захотите создать собственный абстрактный класс TestableTable, вы можете расширить List (таким образом, он уже реализует IEnumerable) и предложить все IQueryable -методы с помощью:

 public SomeType SomeMethodFromIQueryable(…)
 {
      return this.AsQueryable().SomeMthodFromIQueryable(…);
 }

Теперь остались только другие вещи в ITable. Их легко перевести в List -методы, за исключением .Commit(), который можно оставить абстрактным, а затем заглушить и .AssertWasCalled(…).

 var myMock = MockRepository.GenerateStub<TestableTable<MyTable>>(){ new MyTable{…}, …};
 …
 myMock.AssertWasCalled(x => x.Commit());

Надеюсь, это поможет.

П.С .: Я сталкивался с вашим вопросом, когда искал стандартное решение для той же проблемы. Ничего не нашел, поэтому я это реализовал.

0 голосов
/ 01 сентября 2011

Я не знаю linq-to-sql и не знаю ITable.Но когда я смотрю на этот интерфейс, я действительно сомневаюсь, стоит ли вам над ним издеваться.Это слишком сложно.Насмешка над этим может закончиться написанием симулятора всей базы данных, что определенно не имеет смысла.Модульные тесты всегда должны быть максимально простыми.

Я бы порекомендовал использовать реальный класс, который реализует ITable.Чтобы было понятно: не пишите свою собственную реализацию.

...