Mocking Fields
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Mocking Fields
I'm currently using ADOdb as my database wrapper library. Its recommended method of reading rows involves the method MoveNext() and the property $Fields. Because fields is a property, not a method, I can't seem to mock it using SimpleTest. What do I do?
I've determined two possible solutions: I can have MoveNext() set the property for me (don't know how I'd go about doing that), or I can have the class be aware when it's working with a mock and then call getMockFields() if $Fields is not set...
I've determined two possible solutions: I can have MoveNext() set the property for me (don't know how I'd go about doing that), or I can have the class be aware when it's working with a mock and then call getMockFields() if $Fields is not set...
Can't you just set it to what you want it to return?
Code: Select all
$rs =& new MockAdodbResultset($this); //or whatever driver, etc.
$rs->fields = $something;- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Well, currently, I'm using getArray, which returns the entire result set. Here's some usage code via fields:
Documentation here: http://phplens.com/lens/adodb/docs-adodb.htm
Implementation of ADOdb makes it costly to transparently use a subclass (you have to do some reflective programming to make it work). Moving result set creation into its own method will make a partial mock required. I suppose there "should" be some method somewhere out there for grabbing the contents of Field... though checking the source didn't seem to have anything. Of course, editing the actual library file is out of question...
Code: Select all
while (!$recordSet->EOF) {
print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';
$recordSet->MoveNext();
}Implementation of ADOdb makes it costly to transparently use a subclass (you have to do some reflective programming to make it work). Moving result set creation into its own method will make a partial mock required. I suppose there "should" be some method somewhere out there for grabbing the contents of Field... though checking the source didn't seem to have anything. Of course, editing the actual library file is out of question...
I know it is in the docs, my question is more why are you using it? I use getArray() all the time and that is usually more than sufficient for my needs.
I would much rather do:
Saves a line and looks cleaner to me.
I would much rather do:
Code: Select all
foreach ($rs->getArray() as $row) {
echo $row['field_one'], ' ', $row['field_two'], '<br>';
}- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Because it makes things a bit harder to factor out. Consider:
See the duplication.
Ideally (and according to PoEAA), the loadAll function piggybacks off the load function in a manner like:
Code: Select all
function &_load($rs) {
$array = $rs->GetArray();
if (empty($array)) return null;
$id = (int) $array[0][$this->_primaryKey];
$result =& $this->getObject($id);
if ($result != null) return $result;
$result =& $this->_doLoad($id, $array[0]);
$this->setObject($id, &$result);
$this->setObjectByUnique(&$result);
return $result;
}
//should be reimplemented to recycle the _load function, but that
//won't work until we manage to mock $rs->Field, a field.
function &_loadAll($rs) {
$array = $rs->GetArray();
$resultarray = array();
foreach($array as $value) {
$id = (int) $value[$this->_primaryKey];
$result =& $this->getObject($id);
if ($result != null) {
$resultarray[] =& $result;
continue;
}
$result =& $this->_doLoad($id, $value);
$resultarray[] =& $result;
$this->setObject($id, &$result);
$this->setObjectByUnique(&$result);
}
return $resultarray;
}Ideally (and according to PoEAA), the loadAll function piggybacks off the load function in a manner like:
Code: Select all
function &_loadAll($rs) {
$result = array();
while($rs->next()) {
$result[] =& $this->_load($rs);
}
return $result;
}shouldn't something like this work?
Code: Select all
function &$_loadFromRow($row) {
if (empty($row)) return null;
$id = (int) $row[$this->_primaryKey];
$result =& $this->getObject($id);
if ($result != null) return $result;
$result =& $this->_doLoad($id, $row[0]);
$this->setObject($id, &$result);
$this->setObjectByUnique(&$result);
return $result;
}
function &_load($rs) {
$array = $rs->GetArray();
if (empty($array)) return null;
return $this->_loadFromRow($array[0]);
}
function &_loadAll($rs) {
$resultarray = array();
foreach($rs->GetArray() as $row) {
$resultarray[] =& $this->_loadFromRow($row);
}
return $resultarray;
}- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
I think this could be shorter as well (obviously not tested
)
Code: Select all
function &_load($rs) {
return $this->_loadFromRow($rs->getRow());
}- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US