How to check multiple object properties

I get the JSON structure from the API and have to check if the successful response has two specific attributes with specific values.

Main problems:

  • I can not compare the whole object, as there are some properties that can change with each request.
  • I can not write two tests (for each attribute), because it can be considered a successful answer only when both attributes correspond to the correct values.

Example of a successful response:

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

Dirty decision will be

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

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

+7
source share
6 answers

You want to use assertEquals() for each property you want to check. Although you usually want to test only one thing in each test case, it sometimes takes several statements to test this β€œone”. For this reason, several statements are in order.

You can also declare that properties exist in the $response object to avoid notifications. For an example see below:

 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); } 
+2
source

Calculate the difference between the answer and the correct answer, ignoring any excessive values. If there is no difference, everything is in order; if there is, you will receive full 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 can use assertEqual (whatIsWrong (...), array ()), which should output the difference on failure or handle it in almost any way.

+1
source

If assertTrue() stores the boolean value of succesfull response, this is the way I would handle this. 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'; } 
0
source

You can use several statements in one testing method for such cases. Also, use more specific statements, such as assertEquals , when possible, as they will provide better error messages.

 public function testAddAccount() { $response = $this->api->addAccount( '7629428643' ); self::assertTrue($response->success); self::assertEquals('7629428643', $response->id); } 
0
source

As mentioned in some answer, you should use the assertEquals() method. The second part is that you can use several statements. Therefore, if phpunit detects a failure on the first statement, the whole test fails.

Why not use assertTrue() ? Since it is unclear whether you use, for example, if ($object) ... in one place in the code and assertTrue($object); in another.

Also, make sure your procedure is running correctly. Therefore, if you get an exception while trying to get an answer, the test will fail. Although exceptions should be checked as well as test cases. That is, you should try to post an invalid request and throw an assert exception. What a good test looks like - it should check all possible situations, hehe =)

So this is the code you should get:

 public function testAddAccount() { $response = $this->api->addAccount('7629428643'); $this->assertEquals($response->success, true); $this->assertEquals($response->id, '7629428643'); $this->setExpectedException('MyException'); $response = $this->api->addAccount('wrong_account'); } 
0
source

The cleanest way I can think (though it's a matter of taste) would be to add two Boolean expressions and state that the result is two:

 $r1=$response->success === TRUE; $r2=$response->id === '7629428643'; $this->assertEquals(2, $r1+$r2, "Expecting both values to match; got ($r1) and ($r2)"); 

Of course, you can expand this setting to any number of tests with arrays and array_sum()==count() and more nice messages.

0
source

All Articles