How to test multiple properties of an object

I'm getting a JSON structure from an API and need to check, whether the successfull response has two specific attributes with specific values.

Key problems:

  • I cannot compare the whole object, as there are some properties, which may vary with each request
  • I cannot write two tests (for each attribute), because it can be considered as successful response only when both attributes matches the right values.
  • Example successful response:

    {
        'success': true,
        'user_ip': '212.20.30.40',
        'id': '7629428643'
    }
    

    Dirty solution would be

    <?php
    public function testAddAccount() {
        $response = $this->api->addAccount( '7629428643' );
    
        $this->assertTrue(
            $response->success === TRUE &&
            $response->id === '7629428643'
        );
    }
    

    But I think there must be better and cleaner solution, is there?


    You want to use assertEquals() for each property you want to verify. While you typically want to test only one thing in each test case, sometimes multiple assertions are required in order to test that "one thing". For this reason, multiple assertions are okay.

    You may also want to assert that the properties exist on the $response object to avoid notices. See the following for an example:

    public function testAddAccount() {
        // Attempt to create an account.
        $response = $this->api->addAccount('7629428643');
    
        // Verify that the expected properties are present in the response.
        $this->assertObjectHasAttribute('success', $response);
        $this->assertObjectHasAttribute('id', $response);
    
        // Verify the values of the properties.
        $this->assertEquals(true, $response->success);
        $this->assertEquals('7629428643', $response->id);
    }
    

    Compute the difference between the response and the right answer ignoring any excessive values. If there's no difference, everything's fine; if there is, you'll get the complete information.

    //some examples
    $responseValues = array('success' => true, 'user_ip' => '212.20.30.40', 'id' => '7629428643'); //success
    $errorResponseValues = array('success' => false, 'user_ip' => '212.20.30.40', 'id' => '7629428643'); //failure
    $errorResponseValues2 = array('success' => false, 'user_ip' => '212.20.30.40', 'id' => '123'); //failure
    
    $expectedValues = array('success' => true, 'id' => '7629428643'); //what is success
    
    function whatIsWrong($reality, $expectation)
    {
        return array_uintersect_assoc($reality, $expectation, function($a, $b){return (int)($a == $b);}); //This is slightly dirty, I think the final implementation is up to you
    }
    
    var_dump(whatIsWrong($responseValues, $expectedValues)); //array()
    var_dump(whatIsWrong($errorResponseValues, $expectedValues)); //array('success' => false)
    var_dump(whatIsWrong($errorResponseValues2, $expectedValues)); //array('success' => false, id => 123)
    

    Then you may use assertEqual(whatIsWrong(...), array()), which should output the difference on failure, or handle it in pretty much any preferred way.


    If assertTrue() stores the boolean of a succesfull response this is the way how I would handle it. Keep in mind that this is a matter of taste .

    private $lastResponse;
    // $id given elsewhere
    public function testAddAccount($id) {
       $this->lastResponse = $this->addAccount($id);
    }
    
    private function addAccount($id) {
       return $this->api->addAccount($id);
    }
    
    private function isLastResponseValid($response){
       return $this->lastResponse->success === TRUE 
       && $this->lastResponse->id === '7629428643';
    }
    
    链接地址: http://www.djcxy.com/p/11078.html

    上一篇: 如何使用Microsoft Speech从语音模式中识别扬声器?

    下一篇: 如何测试一个对象的多个属性