Java Php、克隆对象、添加新方法或覆盖它们

Java Php、克隆对象、添加新方法或覆盖它们,java,php,object,mocking,Java,Php,Object,Mocking,出于测试目的,我尝试“伪造”一些对象。我希望执行以下操作:我有一个对象,并希望添加新方法,或覆盖某些方法。遗憾的是,与Java不同,创建“无名”类是不可能的。好的,我可以通过简单地创建一个新类来实现,但我想通过友好的方式实现 这是一节课: class Test { public function method1() { return 'oldmethod1'; } public function method2() { re

出于测试目的,我尝试“伪造”一些对象。我希望执行以下操作:我有一个对象,并希望添加新方法,或覆盖某些方法。遗憾的是,与Java不同,创建“无名”类是不可能的。好的,我可以通过简单地创建一个新类来实现,但我想通过友好的方式实现

这是一节课:

class Test
{
    public function method1()
    {
        return 'oldmethod1';
    }
    public function method2()
    {
        return 'oldmethod2';
    }
    public static function staticmethod1()
    {
        return 'staticmethod1';
    }
    public static function staticmethod2()
    {
        return 'staticmethod2';
    }
}
现在我想做的是:

$a = new Test();

$b = new CreateMockObjectFromObject($a);
$b->newmethod = function() { return 'newmethod'; };
$b->method2 = function() { return 'method2 is overwritten'; };
$b->staticmethod2 = function() { return 'staticmethod2 overwritten'; };

echo $b->method1().'<br>';
echo $b->method2().'<br>';
echo $b::staticmethod1().'<br>';
echo $b::staticmethod2().'<br>';
我甚至无法想象静态方法会怎么样。如何编写这个helper类,以便所有的模拟/伪造都可以工作?我甚至都没说“const”-s。。。
再一次,我知道这一切都可以通过扩展来完成,但我需要这样做

模拟整个类:

$mock = Mockery::mock('FQ\ClassName');
仅模拟某些方法:

$mock = Mockery::mock('FQ\ClassName[method1, method2]')
在这里,method3、method4、…、methodN的功能与它们在类实现中的功能完全相同

作出期望:

$mock->shouldReceive('method1')
    ->once()
    ->andReturn('a value')
;
做出预期后,对测试中的系统进行操作:

$return = $objectImTesting->performAction($mock);
一旦您采取了行动,您就应该断言,根据您提供的输入,任何返回值都是应该的:

$this->assertEquals('a value', $return);
以上述示例为例,如果以下任一条件为真,则测试将失败:

  • 永远不会调用模拟对象上的method1
  • 多次调用模拟对象上的method1
  • performation
    的返回值不是字面值
    'a value'
现在,您还没有重新发明轮子,而是已经开始编写测试。同样是免费的,您可以获得PHPUnit和mockry提供给您的一切(您认为自己需要多长时间才能在您的mocking框架中支持Demeter链?)

别误会我的意思,如果你只对学习感兴趣的话,那就继续开发你的测试框架吧。然而,在我看来,我不想相信我自己开发的测试框架,以确保我编写的代码正常工作。我宁愿使用开源的东西,并且已经存在了一段时间,这样我晚上可以睡得更舒服

更多信息:


有一些测试框架,比如PHPUnit和Mockery,它们负责在测试期间为您创建模拟对象,因此您不必重新发明轮子。但我想创造经验:)但我认为我们谈论的不是同一件事。你能详细说明你的意思吗?您不能替换phpunity中的方法您可以模拟整个类(包括它们的方法)并规定返回值。您还可以模拟除单个方法之外的整个类。我通常使用PHPUnit作为测试框架,使用mockry作为我的模拟需求。好的,如果你告诉我如何使用PHPUnit,我相信你事实上,我使用PHPUnit。我在考虑编译“runkit”,我只是不相信它可以用PHPUnityeah完成,PHPUnit mocking留下了一些需要改进的地方,但是mockry解决了大部分问题。
$this->assertEquals('a value', $return);