Filina Consulting, Inc.

Testing Methods That Make Static Calls

January 13th, 2016

I had trouble testing a particularly painful codebase. It had static calls and implicit dependencies all over the place, to name just a few problems.

One of the things that it often did was to call static methods that would increment counters in the database and cache stuff. Example:

Record::incrementViews()
 It was making things difficult.

To avoid messing with the original codebase too much, I came up with this quick and dirty way to ignore those dependencies. In my unit test, I'd write 

$this->mockStaticDependency('Record');
  and then make all static calls on it to return null:

public function mockStaticDependency($className)
{
    eval('class '.$className.' { public static function __callStatic($name, $arguments) { return null; } }');
}

It's like overloading the class with a dummy catch-all method. Yes, I know, eval is EVIL.

I think that it would be quite simple to expand this with an array of method names and their output, in case those pesky dependencies return something the Method Under Test needs. But that's for another day.

I just wanted to throw it out there, since I saw many questions on this topic without satisfying answers. I know that dealing legacy code is hard enough without testability problems.

Update 2016-01-16

As per the suggestion in the comments, I tried Patchwork. It was brilliant! Not only does it avoid issues when repeatedly mocking the same class, it allows you to easily mock specific methods and provide any implementation, like returning test data. Here is how to do the same as above with Patchwork:

Patchwork\replace('Record::incrementViews', function() {
    return null;
});

Regarding adding an implementation, say we have a method 

Record::findById($id)
. We can use Patchwork to return the data we need.

Patchwork\replace('Record::findById', function($id) {
    return array('id'=>$id, 'name'=>'Anna');
});

In short, Patchwork is really the way to go to test untestable code.

Comments

Gundars January 13th, 2016 Not only it's evil, it's also mostly disabled, but this still is better than most answers in the subject
Spudley January 13th, 2016 For testing code like this, I've found the Patchwork library to be invaluable.

http://antecedent.github.io/patchwork/

Patchwork basically provides monkey-patching for PHP. It makes it much easier to write good tests for a lot of the crusty code I have to work with.

Just do Patchwork\replace('Classname::method', function() { /*do nothing*/}); at the start of your test, and Patchwork\undoAll() in your teardown. Job done.
Anna January 13th, 2016 Awesome! That's exactly what I've been looking for. I'll definitely try it. I'll update the post after that.
Ben Ramsey January 25th, 2016 I thought I'd point out that you may also do the same with Mockery: https://github.com/padraic/mockery

When testing in this way, you're injecting a new class with the same name. If using an autoloader, and the real version of the class gets loaded first in a different test, you'll encounter errors (also true if your eval'd version gets loaded first and a later test expects the real class). So, you'll need to run your tests in isolation. You can do this with PHPUnit annotations "@runInSeparateProcess" and "@preserveGlobalState disabled". This method of testing is impossible to use if using "require/include" to include files, rather than an autoloader.

I gave a recent talk on this, where I showed some examples: https://speakerdeck.com/ramsey/mocking-with-mockery-ski-php-2016?slide=47

And I wrote an article showing how to test hard dependencies (use of the "new" keyword inside a unit) using mock instances: https://benramsey.com/articles/mocking-hard-dependencies/

Obviously, these kinds of tests aren't ideal and there are ways to refactor around this, but it's great to know we have options for testing legacy code without having to do full rewrites.
HebrikdPlemo December 15th, 2018 Качественную обувь всегда тяжело найти. Связано это прежде всего с тем, что стильные кроссовки дорого стоят, а найти что-то оригинальное по низкой цене всегда тяжко. Если вы не знаете, в каком магазине купить кроссовки, рекомендуем рассмотреть шанс заказа кроссовок в интернет-магазинах.

Интернет-магазин брендовых кроссовок Reebok Sneakers-Top.ru

Сегодня крутые кроссы вы можете найти на кроссовки мужские купить в москве где есть большое количество кроссовок любых размеров и цветов. Интернет-магазин является дисконтным, из-за этого цены в нём низкие. На сайте есть достаточно кроссовок для парней и женщин. Вы найдёте отклики клиентов, которые покупали разные модели Nike и Puma.

Если вас привлекла какая-то определенная модель, вы можете сделать звонок по телефону 8-(800)-111-22-33, где вам всё подскажут. На ресурсе находится много кроссовок разных моделей. Вы можете подобрать в интернет-магазине кроссовки для спорта или классические модели.

На портале купить кроссовки зимние мужские находится возможность купить кроссовки разных брендов. Вы можете также пройти регистрацию и дать одобрение на рассылку. Благодаря этому вы сможете узнавать первым о всех акциях ресурса.

Заказать фирменные мужские кроссовки в МО

В наши дни заказать оригинальные кроссовки в столице не так уж и просто. Необходимо ехать в ТЦ, где цены невероятно сильно высокие. Чтобы не платить двойную стоимость в фирменных магазинах, оригинальные кроссовки можно заказывать и через сеть. В компании очень много вариантов разных брендов. Если вас заинтересовала определенная модель из новой коллекции, вам её помогут выбрать.

Если вы хотите купить по скидке кроссовки из старой коллекции, это также можно сделать. В фирме моментальная доставка. После того, как вы оформите заказ, с вами свяжется консультант и уточнит адрес доставки. Надо выделить, что доставка по столице происходит в день заказа.

На фирменные кроссовки Adidas и New Balance часто проходят акции. Купить кроссовки Nike вы можете на ресурсе со скидкой. На некоторые модели скидка может доходить до -50%. Более точную стоимость подсказать вам смогут администраторы интернет-магазина. Если вам не подойдёт какая-то определенная модель после доставки, вы её можете также вернуть. Возврат товара проходит невероятно быстро.

Оплату вы можете сделать через банк. При желании сформировать заказ вы можете позвонив в контакт-центр или через веб-портал, перейдя на Sneakers-Top.ru, где оформление заказа проходит очень быстро.
NamxokBoons December 21st, 2018 How Installment Loans Would Assist?

When one requires cash in hand at once, the most trusty solution to get it is to apply to installment loans that have historically been known as the most practicable and timely for really big purchasing. Installment loan constitutes a close-end lend, presuming a fixed date for start and finish, which is identified at the time of application process. Everyone can select how frequently he will pay back. For instance, every borrower could depend on the loan type, being formed as a monthly payment with twenty four similar parts within the period of 2 years.

Taking into account types of installment loans, you can pop up between that secured and unsecured one. Unsecured kind constitutes signature loan as it might be drawn up only with agreement signing and verification of your purposes in such a way. Secured loan should be supported by bail that might be changed in the event of contingencies. Let's analyse an example, automobile loan is usually substantiated by the vehicle you take money for. Therefore, TN bad credit installment loans are a genuine rescue to receive cash in hand on good terms.

Ideas to Get Installment Loans with Bad Credits

To tell the truth, you dispose just 2 way outs. The 1st one presumes to go to a banking establishment, but consider that the reasons for lending installment loans are really confined: mortgage, vehicle, educational, and personal loans. To add to it, banking establishments dispose severe requirements for such loans, especially in case if you want an unsecured kind. Lenders with marginal credits have to search after a co-signer that has to be creditworthy and trusty. Moreover, banks require a irritating and time-taking application process that won't do if you hasten.

One more variant and efficient solution in this situation is to count on our client-oriented services and take installment loans without bad consequences. We secure the most flexible conditions for your certain situation, providing profitable advantages and privileges. Make sure of them yourself!

Why to Have Installment Loans at Our Service?

By turning to us, you are able to bank on these values:
Easy and fast|Fast and simple. Our website esteems your time and would like to keep it by offering comfortable online application process. As you can't lose several weeks on getting 'approved' and having your cash in hand , we render opportune responses and variants from direct creditors.

Real money at hand. Our terms are easy and customizable; for this reason, we distinguish ourselves by a upright scheme of work with no additional charges, signifying that we render money help when you need it most of all with no questions asked.

Debtees for your case. We cooperate with trusty and certified debtees from all over the U.S., who would like to assist you!|

Less than perfect credit score shouldn't be called the last sentence. While many banking establishments and debtees refuse in applying for loan, we will do our best to select the most suitable solution for your situation. We respect every our client and wish to provide an individual approach!

Charges you will be able to afford. Have you looked through these enormous rates by opening rivals' sites? We realize them too! Therefore, we prefer to take care of customers than to make fast money on their troubles.

No credit checks. We see your point why you have found us; thus, we don't take account of your score by giving you an opportunity both to possess money and develop your credit score for the future, depicting what a responsible debtor you are!

Reflect upon Installment Loans?

Don't hesitate and call us to have more details about installment loans and specifications https://maybeloan.com/installment-loans/ia-usa-il . Our specialists are online on twenty-four-hour basis and usually desire to help you, that's why you will see an answer within the shortest timeframes. Don't rely on the better times to dispose money, assume them right away with us!

Phone: +1 514-918-7866 | E-mail: me@afilina.com