Ухххх ...... Если вы храните все свои тестовые данные в файлах XML. Вы только что изменили одну базу данных на другую. Это не в базе данных . В PHP вы бы использовали что-то вроде этого.
class MemoryProductDB {
private $products;
function MemoryProductDB() {
$this->products = array();
}
public function find($index) {
return $this->products[$index];
}
public function save($product) {
$this->products[$product['index']] = $product;
}
}
Вы заметили, что все мои данные хранятся в массиве памяти и извлекаются из массива памяти. Это простая в памяти база данных .
ИМХО, если вы используете XML для хранения тестовых данных, то вы действительно не отключили зависимости от модели и базы данных эффективно. Независимо от того, насколько сложны ваши бизнес-правила, когда они касаются базы данных, все, что они на самом деле делают, - это функциональность CRUD (создание, получение, обновление и удаление).
Если вы работаете в модели с несколькими объектами из базы данных, то, возможно, вам нужно объединить все эти объекты в один объект и попросить модель использовать этот один объект. Примером может служить order
, состоящий из продуктов. Не извлекайте продукты, а сохраняйте их. Получайте заказы, затем сохраняйте заказы, и ваша модель будет работать с заказами. Модель не должна ничего знать о продуктах.
Это называется гранулярностью абстракции.
[Изменить]
Был очень хороший вопрос в комментариях. При тестировании с базой данных в памяти нам не важно, как работает выбор в базе данных. Прежде всего, контроллер должен иметь функциональность в базе данных для подсчета количества возможных записей, к которым можно получить доступ для подкачки. IMDb (в базе данных памяти) должен просто отправить номер. Контроллер никогда не должен заботиться о том, что это за число. То же самое с фактическими записями. Надеюсь, все, что делает ваш контроллер, отображает то, что он возвращает из IMDb.
[править]
Вы никогда не должны тестировать свои контроллеры модульной моделью и imdb. Код установки для IMDB будет иметь много трения. Вместо этого при модульном тестировании контроллера вам необходимо выполнить модульное тестирование фиктивной, заглушки, поддельной модели. Лучшее использование imdb - во время интеграционного теста или при модульном тестировании модели. Разве IMDB не подделка?
Мой сценарий:
- В моем клиенте я использую плагин для таблицы. DataTables . Обработка на стороне сервера.
- Клиент GET запрашивает элементы в таблице
product.get(5,10)
. Возвращаемые данные будут закодированы в формате JSON.
Модель будет отвечать за формирование JSON при извлечении информации из шлюза в базу данных. Шлюз - это просто фасад над базой данных. Я издеватель, так что мой шлюз - это шутка, а не шлюз в памяти.
public function testSkuTable() {
$skus = array(
array('id' => '1', 'data' => 'data1'),
array('id' => '2', 'data' => 'data2'),
array('id' => '3', 'data' => 'data3'));
$names = array(
'id',
'data');
$start_row = $this->parameters['start_row'];
$num_rows = $this->parameters['num_rows'];
$sort_col = $this->parameters['sort_col'];
$search = $this->parameters['search'];
$requestSequence = $this->parameters['request_sequence'];
$direction = $this->parameters['dir'];
$filterTotals = 1;
$totalRecords = 1;
$this->gateway->expects($this->once())
->method('names')
->with($this->vendor)
->will($this->returnValue($names));
$this->gateway->expects($this->once())
->method('skus')
->with($this->vendor, $names, $start_row, $num_rows, $sort_col, $search, $direction)
->will($this->returnValue($skus));
$this->gateway->expects($this->once())
->method('filterTotals')
->will($this->returnValue($filterTotals));
$this->gateway->expects($this->once())
->method('totalRecords')
->with($this->vendor)
->will($this->returnValue($totalRecords));
$expectJson = '{"sEcho": '.$requestSequence.', "iTotalRecords": '.$totalRecords.', "iTotalDisplayRecords": '.$filterTotals.', "aaData": [ ["1","data1"],["2","data2"],["3","data3"]] }';
$actualJson = $this->skusModel->skuTable($this->vendor, $this->parameters);
$this->assertEquals($expectJson, $actualJson);
}
Вы заметите, что с этим модульным тестом меня не интересует, как будут выглядеть данные. $skus
даже не выглядит как настоящая схема таблицы. Просто я возвращаю записи. Вот актуальный код для модели:
public function skuTable($vendor, $parameterList) {
$startRow = $parameterList['start_row'];
$numRows = $parameterList['num_rows'];
$sortCols = $parameterList['sort_col'];
$search = $parameterList['search'];
if($search == null) {
$search = "";
}
$requestSequence = $parameterList['request_sequence'];
$direction = $parameterList['dir'];
$names = $this->propertyNames($vendor);
$skus = $this->skusList($vendor, $names, $startRow, $numRows, $sortCols, $search, $direction);
$filterTotals = $this->filterTotals($vendor, $names, $startRow, $numRows, $sortCols, $search, $direction);
$totalRecords = $this->totalRecords($vendor);
return $this->buildJson($requestSequence, $totalRecords, $filterTotals, $skus, $names);
}
Первая часть метода разбивает отдельные параметры из $parameterList
, который я получаю из запроса get. Остальные звонки на шлюз. Вот один из методов:
public function skusList($vendor, $names, $start_row, $num_rows, $sort_col, $search, $direction) {
return $this->skusGateway->skus($vendor, $names, $start_row, $num_rows, $sort_col, $search, $direction);
}