SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Question PHPUnit Exception

    Hello

    I have the following code that creates a new user. I am using PHPUnit to prepare test cases but however my code coverage is unable to cover the exception case i.e.
    Code:
    throw new Exception(__CLASS__ . ': Invalid data');
    .

    Can someone please show me how to cover the exception case in phpunit using assertInstanceOf() or something else?


    Code:
    ​
    /**
    * Creates a new user
    *
    * @param string            $email
    * @param UserType       $UserType
    * @param string            $prefix
    * @param string            $customFromName
    * @param string            $customFromEmail
    * @param string            $signature
    *
    * @return UserID
    * @throws Exception If Invalid Data is Provided
    */
    static public function Create($email, UserType $UserType, $prefix, $customFromName, $customFromEmail, $signature)
    {
        if (!$UserType instanceof UserType) {
            throw new Exception(__CLASS__ . ': Invalid data');
        }
    
        $UserID = parent::Create($email, $UserType, $prefix, $customFromName, $customFromEmail, $signature, true);
    
        return $UserID;
    
    }


    Many thanks

  2. #2
    SitePoint Evangelist
    Join Date
    Oct 2005
    Location
    Michigan, USA
    Posts
    434
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    That will never happen. PHP will complain if you try to pass in something that isn't a UserType because you have the type hinting in the function signature. Remove that if() it is useless.
    - Robert

  3. #3
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for your reply.

    Please elaborate this statement of yours "PHP will complain"


    Many thanks once again

  4. #4
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    1) Your code is incorrect, it must be

    Code:
    if (!($UserType instanceof UserType)) {
        throw new Exception(__CLASS__ . ': Invalid data');
    }
    Otherwise you're checking if the negation of the $UserType (which is false), is in instance of UserType, which of course it isn't, so the if never ever fires)

    Even if you fix this, it still won't work because,

    2) PHP enforces that you give it an instance of UserType, as @QMonkey ; already said. If you don't, you get an error like:

    Catchable fatal error: Argument 2 passed to A::Create() must be an instance of UserType, instance of stdClass given

    3) I don't think you should be testing this at all, since you're basically getting down to testing the PHP core, which is not what unit tests are for -- they are for testing your application. Let the PHP core devs worry about testing the PHP core. If you were to test this you might as well start testing if PHP finds that 1 + 1 equals 2...
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  5. #5
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks ScallioXTX

    So you mean so say that PHPUnit should NOT check for exceptions? If so, then the code coverage does not cover even 90%


    Thanks

  6. #6
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by cancer10 View Post
    Thanks ScallioXTX

    So you mean so say that PHPUnit should NOT check for exceptions? If so, then the code coverage does not cover even 90%


    Thanks
    That's what you took from what I said?
    That is absolutely NOT what I'm saying! PHPUnit should definitely check for exceptions, but it should not check if PHP does indeed throw a fatal error when you pass an object that does not fit a type hint (in your case when you pass the Create function anything other than a UserType instance).

    Your exception is not needed since PHP will check that the object you pass to the Create() function is indeed an instance of UserType. If it isn't, PHP stops with a catchable fatal error. Just like that. No more code will be executed, because you said the function must get a UserType instance but you gave it something else. There is no need you for to throw an exception yourself, since you're double checking something that PHP already checked, which makes no sense.
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  7. #7
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Cool.

    Thanks for the detailed explanation.

  8. #8
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    That's what you took from what I said?
    That is absolutely NOT what I'm saying! PHPUnit should definitely check for exceptions, but it should not check if PHP does indeed throw a fatal error when you pass an object that does not fit a type hint (in your case when you pass the Create function anything other than a UserType instance).

    Your exception is not needed since PHP will check that the object you pass to the Create() function is indeed an instance of UserType. If it isn't, PHP stops with a catchable fatal error. Just like that. No more code will be executed, because you said the function must get a UserType instance but you gave it something else. There is no need you for to throw an exception yourself, since you're double checking something that PHP already checked, which makes no sense.

    Ok so If I understood correctly, I should be using a try/catch block instead of the throw exception one?

    Thanks

  9. #9
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    No. Please read the thread again. All the info is there. There is is no exception, there is only a fatal error if you pass a wrong object.
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  10. #10
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    For completeness sake: a fatal error is not the same thing as an exception, they are two completely different things.
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  11. #11
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    For completeness sake: a fatal error is not the same thing as an exception, they are two completely different things.
    Suppose in the following case:

    Code:
    <?php
    require "/path/does/not/exits";
    ?>
    Is it a good idea to wrap th above code in try catch block since PHP will display a fatal error since its looking for a non-existant file?

  12. #12
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    try catch blocks catch Exceptions, they do NOT catch fatal errors, since that's something else entirely. So to answer to your question, it's not a good idea, because it doesn't do anything. Try it and see for yourself, I encourage you to!
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  13. #13
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the reply, Will try it.


    Can u also tell me how do I cover the following exception case in my PhpUnit test?

    Code:
    $DB->Insert(db query here...);
    
    $lastInsertID = $DB->InsertID();
    
    if (!$lastInsertID) {
    	throw new Exception('Unable to insert new record');
    }

    Thanks

  14. #14
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    1) Your code is incorrect, it must be

    Code:
    if (!($UserType instanceof UserType)) {
        throw new Exception(__CLASS__ . ': Invalid data');
    }
    Otherwise you're checking if the negation of the $UserType (which is false), is in instance of UserType, which of course it isn't, so the if never ever fires)

    One thing I dont understand is that whether we group it using brackets or not, it does not matter as what you said. Consider these 2 examples:

    http://codepad.org/Be5IPz5p
    http://codepad.org/9ed2iiqG

    Can u pls give me an example supporting your statement?


    Thanks

  15. #15
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,067
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by phantom007 View Post
    One thing I dont understand is that whether we group it using brackets or not, it does not matter as what you said. Consider these 2 examples:

    http://codepad.org/Be5IPz5p
    http://codepad.org/9ed2iiqG

    Can u pls give me an example supporting your statement?


    Thanks
    It appears you are right and those parentheses aren't needed (since instanceof has a higher precedence than !).
    I stand corrected
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  16. #16
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    737
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    ok thanks for confirming that,


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •