Расхождения между «фиктивной» базой данных и «реальным» поведением базы данных - PullRequest
3 голосов
/ 28 апреля 2009

Мы используем C # и Linq2SQL с базой данных MS SQL Server. У нас есть mockdatacontext для проведения модульного тестирования. При тестировании мы обнаружили два разных поведения в зависимости от того, используется ли «реальная» или «фиктивная» база данных.

Сценарий 1: Реальная база данных

В базе 5 записей:

db = realDatabase
db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 5 count2 = 6

Сценарий 2: фиктивная база данных

В базе 5 записей:

db= mockDatabase

db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 6 count2 = 6

* База данных «mock» уже знает о новой записи до вызова SubmitChanges (), поэтому она включена в счетчик. Для тестирования нам нужно, чтобы оба поведения были одинаковыми.

Кто-нибудь еще сталкивался с этой проблемой и можете ли вы предложить решение?

Ответы [ 2 ]

7 голосов
/ 30 апреля 2009

ИМО, это распространенная ошибка, которую пытаются симулировать в тестах. Макет не симулятор. Он не должен реализовывать логику, аналогичную оригиналу, он должен просто возвращать жестко закодированные результаты.

Если поведение макета является сложным, вы в конечном итоге тестируете свой макет вместо своего бизнес-кода.

Я использую RhinoMocks, и это будет выглядеть так:

// arrange
IList<Record> testdata = new List<Record>() {a, b, c};
db = MockRepository.GenerateMock<IDatabase>();
db.Stub(x => db.getTable).Return(testdata);

// act: call your unit under test

// assert
db.AssertWasCalled(x => x.InsertOnSubmit(Arg<Record>.Is.Anything));
db.AssertWasCalled(x => x.SubmitChanges());

Он по-прежнему возвращает один и тот же список каждый раз. Для многих случаев этого будет достаточно. Вы все еще можете вернуть другие данные во втором вызове getTable:

db.Stub(x => db.getTable).Return(testdata1);
db.Stub(x => db.getTable).Return(testdata2);

Это всегда специфично для одного теста, но это делает его таким простым.

Edit:

Я должен признать, что я не знаком с Linq2Sql. В моем примере вызовы, которые являются поддельными, являются вызовами Linq2Sql, которые, вероятно, не могут быть смоделированы так легко. Вы, вероятно, должны поместить его в простой интерфейс DAL. Затем вы издеваетесь над этим интерфейсом.

0 голосов
/ 29 апреля 2009

Я бы предположил, что ваша фиктивная база данных (в памяти ??) не является транзакционной и что метод InsertOnSubmit фактически вставляет запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...