duanqian8867 2013-03-23 08:01
浏览 99
已采纳

PHP:保留静态方法并保持可测试性

My static methods are either of the 'helper' variety, e.g. convertToCamelCase(), or of the 'get singleton' variety, e.g. getInstance(). Either way, I am happy for them to live in a helper class.

The helper class needs to be widely available so I am loading it in my layer supertypes. Now, as far as I can see, provided that the helper can be injected into the supertypes, I have maintained full flexibility over testing my code (with the exception of the helper class itself). Does that make sense? Or am I overlooking something?

To look at it another way... it seems to me that difficulty in testing code increases in proportion to the number of calls to static methods, not in proportion to actual number of static methods themselves. By putting all these calls into one class (my helper), and replacing that class with a mock, I am testing code that is free of static calls and related problems.

(I realise that I should work towards getting rid of my Singletons, but that's going to be a longer term project).

  • 写回答

2条回答 默认 最新

  • dqhbuwrwq692118284 2013-03-26 23:43
    关注

    In the case of a static class that is strictly a helper function like "convertToCamelCase" I would probably just have 100% coverage for that function and then consider it a "core" function and not worry about mocking it elsewhere. What is a mock for "convertToCamelCase" going to do anyway..? Perhaps your unit tests start to smell a little like integrations tests if you do it too much, but there's always a bit of a tradeoff between abstracting everything and making your app needlessly complicated.

    As far as singletons it is tricky because you usually have the name of the static class in your code so it becomes problematic to swap it out with a mock object for testing. One thing you could do is wherever you are making your static method calls, start by refactoring to call them this way:

    $instance = call_user_func('MyClass::getinstance');
    

    Then, as you increase your testing coverage, you could begin replacing with something like:

    $instance = call_user_func($this->myClassName . '::getinstance');
    

    So - once you have that, you could swap out and mock MyClass by changing $this->myClassName. You'd have to make sure you're requiring or autoloading the relevant php files dynamically as well.

    Refactoring to use an abstract factory pattern would make things even easier to test but you could start implementing that over time as well

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?