如何Str::shouldReceive? (嘲笑 Illuminate\Support\Str)

Posted

技术标签:

【中文标题】如何Str::shouldReceive? (嘲笑 Illuminate\\Support\\Str)【英文标题】:How to Str::shouldReceive? (mocking Illuminate\Support\Str)如何Str::shouldReceive? (嘲笑 Illuminate\Support\Str) 【发布时间】:2014-08-19 16:59:18 【问题描述】:

我有一个使用 Str::random() 的课程,我想对其进行测试。

但是当我在测试中使用Str::shouldReceive('random') 时,我得到一个 BadMethodCallException 说方法 shouldReceive 不存在。

我也尝试直接模拟该类并将其绑定到 IOC,但它继续执行原始类,生成一个随机字符串而不是我在模拟上设置的返回值。

    $stringHelper = Mockery::mock('Illuminate\Support\Str');
    $this->app->instance('Illuminate\Support\Str', $stringHelper);
    //$this->app->instance('Str', $stringHelper);

    $stringHelper->shouldReceive('random')->once()->andReturn('some password');
    //Str::shouldReceive('random')->once()->andReturn('some password');

【问题讨论】:

【参考方案1】:

您将无法以这种方式模拟 Illuminate\Support\Str(请参阅 mockery docs。这就是我要测试它的方式。

在尝试生成随机字符串的类中,您可以创建一个生成随机字符串的方法,然后在测试中覆盖该方法(代码未实际测试):

    // class under test
    class Foo 
        public function __construct($otherClass) 
            $this->otherClass = $otherClass;
        

        public function doSomethingWithRandomString() 
            $random = $this->getRandomString();
            $this->otherClass->useRandomString($random);
        

        protected function getRandomString() 
            return \Illuminate\Support\Str::random();
        
    

    // test file
    class FooTest 
        protected function fakeFooWithOtherClass() 
            $fakeOtherClass = Mockery::mock('OtherClass');
            $fakeFoo = new FakeFoo($fakeOtherClass);
            return array($fakeFoo, $fakeOtherClass);
        

        function test_doSomethingWithRandomString_callsGetRandomString() 
             list($foo) = $this->fakeFooWithOtherClass();
             $foo->doSomethingWithRandomString();

             $this->assertEquals(1, $foo->getRandomStringCallCount);
        

        function test_doSomethingWithRandomString_callsUseRandomStringOnOtherClassWithResultOfGetRandomString() 
            list($foo, $otherClass) = $this->fakeFooWithOtherClass();

            $otherClass->shouldReceive('useRandomString')->once()->with('fake random');
            $foo->doSomethingWithRandomString();
        
    
    class FakeFoo extends Foo 
        public $getRandomStringCallCount = 0;
        protected function getRandomString() 
            $this->getRandomStringCallCount ++;
            return 'fake random';
        
    

【讨论】:

【参考方案2】:

你不能使用 laravel Mock 因为 Str::random() 不是 Facade。 相反,您可以使用设置测试环境的方法创建一个新类。像这样: ‍‍‍

<?php

namespace App;


use Illuminate\Support\Str;

class Token

    static $testToken =null;
    public static function generate()
        return static::$testToken ?:Str::random(60);
    

    public static function setTest($string)
        static::$testToken = $string;
    

【讨论】:

【参考方案3】:

只要您还使用 IoC 来解决该类的绑定,您尝试的方法就会起作用。

$instance = resolve(\Illuminate\Support\Str::class);
$instance::random();

【讨论】:

以上是关于如何Str::shouldReceive? (嘲笑 Illuminate\Support\Str)的主要内容,如果未能解决你的问题,请参考以下文章

如何用玩笑嘲笑S3?

说出来也许你不信,我被 Linux 终端嘲笑了…….

我被嘲笑了:被查询的列,为啥要放到索引里?(1分钟系列)

我被嘲笑了:被查询的列,为啥要放到索引里?(1分钟系列)

为啥嘲笑 DAO 时 mockito 崩溃?

在Jmockit停止嘲笑