আমি কীভাবে পিএইচপিউনিট মকঅবজেক্টসগুলিকে একটি প্যারামিটারের উপর ভিত্তি করে বিভিন্ন মান ফিরিয়ে আনতে পারি?


141

আমি একটি পিএইচপিউইনিট মক অবজেক্ট পেয়েছি 'return value'যা তার যুক্তি যাই হোক না কেন তা ফিরিয়ে দেয় :

// From inside a test...
$mock = $this->getMock('myObject', 'methodToMock');
$mock->expects($this->any))
     ->method('methodToMock')
     ->will($this->returnValue('return value'));

আমি যা করতে সক্ষম হতে চাই তা হ'ল মক পদ্ধতিতে আর্গুমেন্টের উপর ভিত্তি করে একটি আলাদা মান return আমি এরকম কিছু চেষ্টা করেছি:

$mock = $this->getMock('myObject', 'methodToMock');

// methodToMock('one')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('one'))
     ->will($this->returnValue('method called with argument "one"'));

// methodToMock('two')
$mock->expects($this->any))
     ->method('methodToMock')
     ->with($this->equalTo('two'))
     ->will($this->returnValue('method called with argument "two"'));

তবে এটি পিএইচপিউইনিতকে অভিযোগ করে যদি মকটিকে যুক্তির সাথে ডাকা হয় না 'two', তাই আমি ধরে নিই যে সংজ্ঞাটি methodToMock('two')প্রথমটির সংজ্ঞাটি ওভাররাইট করে।

সুতরাং আমার প্রশ্নটি হল: কোনও পিএইচপিউইনিট মক অবজেক্টের পক্ষে যুক্তিগুলির ভিত্তিতে আলাদা মান ফেরানোর কোনও উপায় আছে কি? এবং যদি তা হয়, কিভাবে?

উত্তর:


125

একটি কলব্যাক ব্যবহার করুন। যেমন (সরাসরি পিএইচপিউইনাইট ডকুমেন্টেশন থেকে):

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnCallbackStub()
    {
        $stub = $this->getMock(
          'SomeClass', array('doSomething')
        );

        $stub->expects($this->any())
             ->method('doSomething')
             ->will($this->returnCallback('callback'));

        // $stub->doSomething() returns callback(...)
    }
}

function callback() {
    $args = func_get_args();
    // ...
}
?>

কলব্যাক () এ যা কিছু প্রসেসিং আপনি করুন এবং যথাযথ হিসাবে আপনার gs আরোগুলির উপর ভিত্তি করে ফলাফলটি ফিরিয়ে দিন।


2
আপনি কি ডকুমেন্টেশনের লিঙ্ক সরবরাহ করতে পারেন? আমি এটি "গুগল" দিয়ে খুঁজে পাচ্ছি না
ক্রিস এরিকসন

6
মনে রাখবেন আপনি অ্যারে পাস করে কলব্যাক হিসাবে কোনও পদ্ধতি ব্যবহার করতে পারেন, যেমন $this->returnCallback(array('MyClassTest','myCallback'))
প্যাট্রিক ফিশার

1
এটির সরাসরি বন্ধ হয়ে
যাওয়াও

7
এটি কেবল বিরল ক্ষেত্রেই ব্যবহার করা উচিত। আমি পরিবর্তে রিটার্নভ্যালুম্যাপ ব্যবহার করার পরামর্শ দেব কারণ এটিতে কলব্যাকে কাস্টম যুক্তি লেখার প্রয়োজন নেই।
হারমান জে। রাডটক III

1
আমি আপনাকে যথেষ্ট ধন্যবাদ দিতে পারি না। এছাড়াও, পিএইচপি সংস্করণ> 5.4 এর সাহায্যে আপনি কলব্যাক হিসাবে একটি বেনামী ফাংশন ব্যবহার করতে পারেন। $this->returnCallback(function() { // ... })
বোরমেনেট

110

সর্বশেষ phpUnit ডক্স থেকে: "। কখনও কখনও একটি stubbed পদ্ধতি মান আলাদা আর্গুমেন্ট একটি পূর্বনির্ধারিত তালিকা উপর নির্ভর করে ফেরত পাঠাবেন আপনি ব্যবহার করতে পারেন returnValueMap () । একটি মানচিত্র তৈরি যে সংশ্লিষ্ট রিটার্ন মান সহযোগীদের আর্গুমেন্ট"

$mock->expects($this->any())
    ->method('getConfigValue')
    ->will(
        $this->returnValueMap(
            array(
                array('firstparam', 'secondparam', 'retval'),
                array('modes', 'foo', array('Array', 'of', 'modes'))
            )
        )
    );

3
পোস্টের লিঙ্কটি পুরানো, সঠিক এখানে রয়েছে: রিটার্নভ্যালুম্যাপ ()
হিজদাভ

48

আমারও অনুরূপ সমস্যা ছিল (যদিও কিছুটা আলাদা ... তর্কগুলির ভিত্তিতে আমার পৃথক পৃথক ফেরতের মানের প্রয়োজন ছিল না, তবে একই ক্রিয়ায় 2 সেট আর্গুমেন্ট পাস হচ্ছে তা নিশ্চিত করার জন্য পরীক্ষা করতে হয়েছিল)। আমি এই জাতীয় কিছু ব্যবহার করে হোঁচট খেয়েছি:

$mock = $this->getMock();
$mock->expects($this->at(0))
    ->method('foo')
    ->with(...)
    ->will($this->returnValue(...));

$mock->expects($this->at(1))
    ->method('foo')
    ->with(...)
    ->will($this->returnValue(...));

এটি নিখুঁত নয়, যেহেতু এটির জন্য foo () এর 2 টি কলের অর্ডার জানা প্রয়োজন, তবে বাস্তবে এটি খুব খারাপ নয়।


28

আপনি সম্ভবত একটি ওওপি ফ্যাশনে কলব্যাক করতে চান:

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnAction()
    {
        $object = $this->getMock('class_name', array('method_to_mock'));
        $object->expects($this->any())
            ->method('method_to_mock')
            ->will($this->returnCallback(array($this, 'returnCallback'));

        $object->returnAction('param1');
        // assert what param1 should return here

        $object->returnAction('param2');
        // assert what param2 should return here
    }

    public function returnCallback()
    {
        $args = func_get_args();

        // process $args[0] here and return the data you want to mock
        return 'The parameter was ' . $args[0];
    }
}
?>

16

আপনি যা চান ঠিক তা নয়, তবে কিছু ক্ষেত্রে এটি সহায়তা করতে পারে:

$mock->expects( $this->any() ) )
 ->method( 'methodToMock' )
 ->will( $this->onConsecutiveCalls( 'one', 'two' ) );

অনকন্টিউন্টকলস - নির্দিষ্ট ক্রমে মানগুলির একটি তালিকা প্রদান করে


4

দুটি স্তরের অ্যারে পাস করুন, যেখানে প্রতিটি উপাদান একটি অ্যারে হয়:

  • প্রথমে পদ্ধতি প্যারামিটার এবং সর্বনিম্ন প্রত্যাবর্তনের মান value

উদাহরণ:

->willReturnMap([
    ['firstArg', 'secondArg', 'returnValue']
])

2

আপনি নিম্নরূপ যুক্তি ফিরিয়ে দিতে পারেন:

$stub = $this->getMock(
  'SomeClass', array('doSomething')
);

$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->returnArgument(0));

আপনি মকিং ডকুমেন্টেশনে দেখতে পাচ্ছেন যে পদ্ধতিটি returnValue($index)প্রদত্ত যুক্তি ফিরিয়ে আনতে দেয়।


0

তুমি কি এরকম কিছু বোঝাতে চাও?

public function TestSomeCondition($condition){
  $mockObj = $this->getMockObject();
  $mockObj->setReturnValue('yourMethod',$condition);
}

আমি মনে করি এটি পিএইচপিউনিট নয়, সিম্পল টেস্ট কোড। তবে না, আমি তা অর্জন করতে চাই না। বলুন আমার কাছে একটি মক অবজেক্ট ছিল যা প্রদত্ত সংখ্যার জন্য একটি শব্দ ফেরত দিয়েছিল। আমার উপহাসের পদ্ধতিতে 1, "দুটি" সাথে 2 বলা হলে "এক" ফিরতে হবে $
বেন ডওলিং

0

আমারও একই রকম সমস্যা ছিল যা আমিও কার্যকর করতে পারিনি (পিএইচপিউনিত সম্পর্কে আশ্চর্যজনকভাবে খুব কম তথ্য আছে)। আমার ক্ষেত্রে, আমি কেবল প্রতিটি পরীক্ষার পৃথক পরীক্ষা করেছি - পরিচিত ইনপুট এবং পরিচিত আউটপুট। আমি বুঝতে পেরেছিলাম যে জ্যাক-অফ-অল ট্রেডস মক অবজেক্টটি তৈরি করার দরকার নেই, আমার কেবল নির্দিষ্ট পরীক্ষার জন্য একটি নির্দিষ্ট একটি প্রয়োজন ছিল এবং এইভাবে আমি পরীক্ষাগুলি আলাদা করে দিয়েছি এবং আমার কোডের পৃথক দিকগুলি পৃথক হিসাবে পরীক্ষা করতে পারি ইউনিট। আমি নিশ্চিত নই যে এটি আপনার জন্য প্রযোজ্য বা নাও হতে পারে তবে আপনি যা পরীক্ষা করতে হবে তা হ'ল এটি।


দুর্ভাগ্যক্রমে আমার পরিস্থিতিতে এটি কাজ করবে না। মোকটি এমন একটি পদ্ধতিতে পাস করা হচ্ছে যা আমি পরীক্ষা করছি এবং পরীক্ষার পদ্ধতিটি বিভিন্ন যুক্তি সহ মক পদ্ধতিটিকে কল করে। আপনি যদিও সমস্যার সমাধান করতে পারেন তা জেনে রাখা আকর্ষণীয়। দেখে মনে হচ্ছে এটি কোনও পিএইচপিউইনিট সীমাবদ্ধতা হতে পারে।
বেন ডওলিং

-1
$this->BusinessMock = $this->createMock('AppBundle\Entity\Business');

    public function testBusiness()
    {
        /*
            onConcecutiveCalls : Whether you want that the Stub returns differents values when it will be called .
        */
        $this->BusinessMock ->method('getEmployees')
                                ->will($this->onConsecutiveCalls(
                                            $this->returnArgument(0),
                                            $this->returnValue('employee')                                      
                                            )
                                      );
        // first call

        $this->assertInstanceOf( //$this->returnArgument(0),
                'argument',
                $this->BusinessMock->getEmployees()
                );
       // second call


        $this->assertEquals('employee',$this->BusinessMock->getEmployees()) 
      //$this->returnValue('employee'),


    }

-2

চেষ্টা করুন:

->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));

এই উত্তরটি মূল প্রশ্নের ক্ষেত্রে প্রযোজ্য নয়, তবে এটি আমার মতো একই সমস্যার বিবরণ দেয়: প্যারামিটারগুলির একটি নির্দিষ্ট সেট সরবরাহ করা হয়েছে তা যাচাই করুন । PHPUnit এর () এর সাথে একাধিক যুক্তি গ্রহণ করা হয়, প্রতিটি প্যারামিটারের জন্য একটি ম্যাথার cher
তাজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.