Re: [fw-general] How to unit test a method that creates a Zend\Db\Sql\Sql object?
On Tue, Dec 10, 2013 at 2:34 PM, Julian Vidal jul...@julianvidal.com wrote: I have this method that I would like to unit test. Since it's creating the Sql object inside the method, I can't mock it up. Initially I thought about making Sql be an instance property except that I'd have to reset it every time I use it in other methods and this will most likely lead to hard to debug errors. What's the common pattern for testing these kinds of methods? I would write a separate method for the SQL creation. That way you can unit test against the Sql instance that returns, and only do integration or functional testing on the method that consumes it. So: public function prepareConfigSql(\Zend\Db\Adapter\Adapter $adapter) { $sql = new Sql($adapter); $select = $sql-select()-from('languages'); return $select; } Inside your getConfigFromDb() method, you'd do this: $select = $this-prepareConfigSql($this-getSlaveDbAdapter()); This allows you to unit test the prepareConfigSql() method and do assertions on the Select instance it returns, even using a mock adapter if desired. Here's a link to the gist in case this syntax highlighter screws things up: https://gist.github.com/poisa/7898032 public function getConfigFromDb() { if (!is_null($this-configInDb)) { return $this-configInDb; } $sql = new Sql($this-getSlaveDbAdapter()); $select = $sql-select() -from('languages'); $statement = $sql-prepareStatementForSqlObject($select); $results = $statement-execute(); $results-buffer(); $return = array(); foreach ($results as $r) { $return[] = $r; } $this-configInDb = $return; return $return; } -- Matthew Weier O'Phinney Project Lead| matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: fw-general@lists.zend.com Info: http://framework.zend.com/archives Unsubscribe: fw-general-unsubscr...@lists.zend.com
Re: [fw-general] How to unit test a method that creates a Zend\Db\Sql\Sql object?
Matthew, Thanks for your answer. Going a little step further... as you can imagine I'll be using the Sql object _many_ times in application. Does it makes sense to create an Sql service with mainly 4 methods that given an adapter, each return a Select(), Insert(), Update(), Delete() objects? (without the from(), since I'll need to change that in every case) Is this overkill? In my head it sounds reasonable but since I've never seen it done I might be missing something. Julian. On Thu, Dec 12, 2013 at 10:00 AM, Matthew Weier O'Phinney matt...@zend.comwrote: On Tue, Dec 10, 2013 at 2:34 PM, Julian Vidal jul...@julianvidal.com wrote: I have this method that I would like to unit test. Since it's creating the Sql object inside the method, I can't mock it up. Initially I thought about making Sql be an instance property except that I'd have to reset it every time I use it in other methods and this will most likely lead to hard to debug errors. What's the common pattern for testing these kinds of methods? I would write a separate method for the SQL creation. That way you can unit test against the Sql instance that returns, and only do integration or functional testing on the method that consumes it. So: public function prepareConfigSql(\Zend\Db\Adapter\Adapter $adapter) { $sql = new Sql($adapter); $select = $sql-select()-from('languages'); return $select; } Inside your getConfigFromDb() method, you'd do this: $select = $this-prepareConfigSql($this-getSlaveDbAdapter()); This allows you to unit test the prepareConfigSql() method and do assertions on the Select instance it returns, even using a mock adapter if desired. Here's a link to the gist in case this syntax highlighter screws things up: https://gist.github.com/poisa/7898032 public function getConfigFromDb() { if (!is_null($this-configInDb)) { return $this-configInDb; } $sql = new Sql($this-getSlaveDbAdapter()); $select = $sql-select() -from('languages'); $statement = $sql-prepareStatementForSqlObject($select); $results = $statement-execute(); $results-buffer(); $return = array(); foreach ($results as $r) { $return[] = $r; } $this-configInDb = $return; return $return; } -- Matthew Weier O'Phinney Project Lead| matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: fw-general@lists.zend.com Info: http://framework.zend.com/archives Unsubscribe: fw-general-unsubscr...@lists.zend.com
Re: [fw-general] How to unit test a method that creates a Zend\Db\Sql\Sql object?
This is what I meant on the previous email: ?php namespace Application\Model\Service; use Zend\Db\Sql\Sql; use Zend\Db\Adapter\Adapter; use Application\Model\DbAdapter\MasterSlaveDbAdapterAwareTrait; use Application\Model\DbAdapter\MasterSlaveDbAdapterAwareInterface; class SqlFactory implements MasterSlaveDbAdapterAwareInterface { use MasterSlaveDbAdapterAwareTrait; /** * @param Adapter $adapter * * @return \Zend\Db\Sql\Select */ public function createSelect(Adapter $adapter = null) { if (is_null($adapter)) { $adapter = $this-getSlaveDbAdapter(); } $sql = new Sql($adapter); return $sql-select(); } /** * @param Adapter $adapter * * @return \Zend\Db\Sql\Insert */ public function createInsert(Adapter $adapter = null) { if (is_null($adapter)) { $adapter = $this-getMasterDbAdapter(); } $sql = new Sql($adapter); return $sql-insert(); } /** * @param Adapter $adapter * * @return \Zend\Db\Sql\Update */ public function createUpdate(Adapter $adapter = null) { if (is_null($adapter)) { $adapter = $this-getMasterDbAdapter(); } $sql = new Sql($adapter); return $sql-update(); } /** * @param Adapter $adapter * * @return \Zend\Db\Sql\Delete */ public function createDelete(Adapter $adapter = null) { if (is_null($adapter)) { $adapter = $this-getMasterDbAdapter(); } $sql = new Sql($adapter); return $sql-delete(); } } On Thu, Dec 12, 2013 at 1:48 PM, Julian Vidal jul...@julianvidal.comwrote: Matthew, Thanks for your answer. Going a little step further... as you can imagine I'll be using the Sql object _many_ times in application. Does it makes sense to create an Sql service with mainly 4 methods that given an adapter, each return a Select(), Insert(), Update(), Delete() objects? (without the from(), since I'll need to change that in every case) Is this overkill? In my head it sounds reasonable but since I've never seen it done I might be missing something. Julian. On Thu, Dec 12, 2013 at 10:00 AM, Matthew Weier O'Phinney matt...@zend.com wrote: On Tue, Dec 10, 2013 at 2:34 PM, Julian Vidal jul...@julianvidal.com wrote: I have this method that I would like to unit test. Since it's creating the Sql object inside the method, I can't mock it up. Initially I thought about making Sql be an instance property except that I'd have to reset it every time I use it in other methods and this will most likely lead to hard to debug errors. What's the common pattern for testing these kinds of methods? I would write a separate method for the SQL creation. That way you can unit test against the Sql instance that returns, and only do integration or functional testing on the method that consumes it. So: public function prepareConfigSql(\Zend\Db\Adapter\Adapter $adapter) { $sql = new Sql($adapter); $select = $sql-select()-from('languages'); return $select; } Inside your getConfigFromDb() method, you'd do this: $select = $this-prepareConfigSql($this-getSlaveDbAdapter()); This allows you to unit test the prepareConfigSql() method and do assertions on the Select instance it returns, even using a mock adapter if desired. Here's a link to the gist in case this syntax highlighter screws things up: https://gist.github.com/poisa/7898032 public function getConfigFromDb() { if (!is_null($this-configInDb)) { return $this-configInDb; } $sql = new Sql($this-getSlaveDbAdapter()); $select = $sql-select() -from('languages'); $statement = $sql-prepareStatementForSqlObject($select); $results = $statement-execute(); $results-buffer(); $return = array(); foreach ($results as $r) { $return[] = $r; } $this-configInDb = $return; return $return; } -- Matthew Weier O'Phinney Project Lead| matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: fw-general@lists.zend.com Info: http://framework.zend.com/archives Unsubscribe: fw-general-unsubscr...@lists.zend.com
Re: [fw-general] How to unit test a method that creates a Zend\Db\Sql\Sql object?
On Thu, Dec 12, 2013 at 12:48 PM, Julian Vidal jul...@julianvidal.com wrote: Matthew, Thanks for your answer. Going a little step further... as you can imagine I'll be using the Sql object _many_ times in application. Does it makes sense to create an Sql service with mainly 4 methods that given an adapter, each return a Select(), Insert(), Update(), Delete() objects? (without the from(), since I'll need to change that in every case) Is this overkill? In my head it sounds reasonable but since I've never seen it done I might be missing something. If it helps you accomplish your testing goals, and offers a clean separation of concerns, then yes, do it! Sometimes you end up with more smaller, dedicated classes when doing these things, and it seems more complex from the outside, but internally, it's actually less complex, and easier to identify when and where things go wrong later. On Thu, Dec 12, 2013 at 10:00 AM, Matthew Weier O'Phinney matt...@zend.comwrote: On Tue, Dec 10, 2013 at 2:34 PM, Julian Vidal jul...@julianvidal.com wrote: I have this method that I would like to unit test. Since it's creating the Sql object inside the method, I can't mock it up. Initially I thought about making Sql be an instance property except that I'd have to reset it every time I use it in other methods and this will most likely lead to hard to debug errors. What's the common pattern for testing these kinds of methods? I would write a separate method for the SQL creation. That way you can unit test against the Sql instance that returns, and only do integration or functional testing on the method that consumes it. So: public function prepareConfigSql(\Zend\Db\Adapter\Adapter $adapter) { $sql = new Sql($adapter); $select = $sql-select()-from('languages'); return $select; } Inside your getConfigFromDb() method, you'd do this: $select = $this-prepareConfigSql($this-getSlaveDbAdapter()); This allows you to unit test the prepareConfigSql() method and do assertions on the Select instance it returns, even using a mock adapter if desired. Here's a link to the gist in case this syntax highlighter screws things up: https://gist.github.com/poisa/7898032 public function getConfigFromDb() { if (!is_null($this-configInDb)) { return $this-configInDb; } $sql = new Sql($this-getSlaveDbAdapter()); $select = $sql-select() -from('languages'); $statement = $sql-prepareStatementForSqlObject($select); $results = $statement-execute(); $results-buffer(); $return = array(); foreach ($results as $r) { $return[] = $r; } $this-configInDb = $return; return $return; } -- Matthew Weier O'Phinney Project Lead| matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: fw-general@lists.zend.com Info: http://framework.zend.com/archives Unsubscribe: fw-general-unsubscr...@lists.zend.com -- Matthew Weier O'Phinney Project Lead| matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: fw-general@lists.zend.com Info: http://framework.zend.com/archives Unsubscribe: fw-general-unsubscr...@lists.zend.com