Note that there are some explanatory texts on larger screens.

plurals
  1. PO"Static methods are death to testability" - alternatives for alternative constructors?
    primarykey
    data
    text
    <p>It is being said that <a href="http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/">"static methods are death to testability"</a>. If that is so, what is a viable alternative pattern for the below?</p> <pre><code>class User { private $phone, $status = 'default', $created, $modified; public function __construct($phone) { $this-&gt;phone = $phone; $this-&gt;created = new DateTime; $this-&gt;modified = new DateTime; } public static function getByPhone(PDO $pdo, $phone) { $stmt = $pdo-&gt;prepare('SELECT * FROM `users` WHERE `phone` = :phone'); $stmt-&gt;execute(compact('phone')); if (!$stmt-&gt;rowCount()) { return false; } $record = $stmt-&gt;fetch(PDO::FETCH_ASSOC); $user = new self($record['phone']); $user-&gt;status = $record['status']; $user-&gt;created = new DateTime($record['created']); $user-&gt;modified = new DateTime($record['modified']); return $user; } public function save(PDO $pdo) { $stmt = $pdo-&gt;prepare( 'INSERT INTO `users` (`phone`, `status`, `created`, `modified`) VALUES (:phone, :status, :created, :modified) ON DUPLICATE KEY UPDATE `status` = :status, `modified` = :modified'); $data = array( 'phone' =&gt; $this-&gt;phone, 'status' =&gt; $this-&gt;status, 'created' =&gt; $this-&gt;created-&gt;format('Y-m-d H:i:s'), 'modified' =&gt; date('Y-m-d H:i:s') ); return $stmt-&gt;execute($data); } ... } </code></pre> <p>This is just a cut down example. The class has a few more methods and properties and there's more validation when writing to the database etc. The guiding design principle behind this class is that it models a user as an object. Some of the object's properties cannot be modified after it has been created, like the phone number (which acts as a primary id), the date the user was created and so on. Other properties can only be altered according to strict business rules, which all have strictly validating setters and getters.</p> <p>The object does not represent a database record per se, the database is only seen as <em>one</em> possible form of permanent storage. As such, a database connector is not stored in the object but rather needs to be injected every time the object needs to interact with the database.</p> <p>When a new user is created, this looks like:</p> <pre><code>$user = new User('+123456789'); </code></pre> <p>When an existing user is restored from permanent storage, that looks like:</p> <pre><code>$pdo = new PDO('...'); $user = User::getByPhone($pdo, '+123456789'); </code></pre> <p>If I were to take the "death to testability" line seriously, this is supposedly bad. I am perfectly able to test this object though, since it is fully dependency injected and the <code>static</code> methods have no state. How could I do this any differently and avoid the use of <code>static</code> methods? Or rather, what exactly argues against <code>static</code> in this case? What makes this particular use of <code>static</code> methods so hard to test?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload