SitePoint Sponsor

User Tag List

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

    Question PHPUnit - Testing Switch/Default cases

    Hi All

    I have a question about PHPUnit. I want to write a test case for the following Message class and want to cover the default: case in my test cases by passing an invalid $type in the isValidMessageType() method. Just to give you a proper scenario of when this will be useful, suppose the developer adds another type i.e. 3 in the isValidMessageType() method but forgets to add a switch case in the SendMessage() method, in that scenario the default case will throw an exception.


    PHP Code:
    class Message
    {

        public function 
    isValidMessageType($type)
        {
            return (
    $type == || $type == 2)
        }

        public function 
    SendMessage($type)
        {

            if(!
    $this->isValidMessageType($type)){
                throw new 
    Exception('Invalid Message type');
            }

            switch (
    $type) {
                case 
    1:
                    
    // do something
                    
    break;
                case 
    2:
                    
    // do something
                    
    break;
                default:
                    throw new 
    Exception('Invalid Message type');
            }

        }


    Can someone please help me how to achieve this?


    Thanks in advance

  2. #2
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    338
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    You need to first install PHPUnit, I assume this is done already. Next, create a new class file with a class called MessageTest that extends from PHP Unit's base TestCase class. Finally, add two methods to this test class: testIsValidMessage() and testSendMessage(), use common testing methodology such as assertTrue() and assertEquals() with mock message objects(objects that you create for testing purposes, they may or may not have correct states). The first method should be very simple to test(2-3 assertTrue() should be enough), the second may be a bit difficult and will require some creativity(since it's a void method that returns nothing).

    Also this may not be relevant to your question, but I believe your class design is flawed to begin with. A message class whose behavior depends on type-code is a poor OO design, instead you are better off either using Inheritance/Polymorphism to create specialized message sub-classes corresponding to a single message type, or applying composite/strategy design pattern to compensate behaviors that alter depending on the message type. The problem is, assume you have another method similar to sendMessage() that depends on the type of your message, you will end up writing another switch...case statement checking exactly the same type code again. Switch...case statement itself is usually considered a bad smell in programming, duplicated switch...case statement is pretty much always a sign of improper design. I personally only use switch...case in factory classes(and in fact, using dynamic method call even factory methods can eliminate switch...case statements), and make sure the same switch condition/type is checked no more than once. Read the book Pro PHP Refactoring and you will find techniques such as Replace Typecode with State/Strategy and Replace Conditionals/Switches with Polymorphism, these are all adapted from Martin Fowler's original book on refactoring and will help you design a better software.

  3. #3
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    4,807
    Mentioned
    141 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cancer10 View Post
    Can someone please help me how to achieve this?
    The short answer is you can't! Your if statement will throw the exception before your switch statement is ever considered. So the defafult case in your switch statement is redundant and should be removed.
    Be sure to congratulate xMog on earning April's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  4. #4
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    725
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    You need to first install PHPUnit, I assume this is done already. Next, create a new class file with a class called MessageTest that extends from PHP Unit's base TestCase class. Finally, add two methods to this test class: testIsValidMessage() and testSendMessage(), use common testing methodology such as assertTrue() and assertEquals() with mock message objects(objects that you create for testing purposes, they may or may not have correct states). The first method should be very simple to test(2-3 assertTrue() should be enough), the second may be a bit difficult and will require some creativity(since it's a void method that returns nothing).
    Will following this approach add to code coverage for the original "Message" class?


    One more question <offtopic>

    Suppose I have a method GetUserDetails() in the class "User", and there are 10 possible test cases, should I be adding all those 10 test cases in the testGetUserDetails() method in the UserTest class or do I write each cases in separate methods like testGetUserDetailsCaseA(), testGetUserDetailsCaseB(), testGetUserDetailsCaseC() etc etc??


    Thanks for your reply.

  5. #5
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    725
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cpradio View Post
    The short answer is you can't! Your if statement will throw the exception before your switch statement is ever considered. So the defafult case in your switch statement is redundant and should be removed.
    Yes I know which is why I gave you a scenario in my original post that why I have to have 2 separate condition checking...

    Just to give you a proper scenario of when this will be useful, suppose the developer adds another type i.e. 3 in the isValidMessageType() method but forgets to add a switch case in the SendMessage() method, in that scenario the default case will throw an exception.

  6. #6
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    4,807
    Mentioned
    141 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cancer10 View Post
    Yes I know which is why I gave you a scenario in my original post that why I have to have 2 separate condition checking...
    Then you'd likely catch it when he tests his code to verify the message appeared. That becomes an Integration test and no longer a Unit Test.
    Be sure to congratulate xMog on earning April's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  7. #7
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    725
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    One more question <offtopic>

    Suppose I have a method GetUserDetails() in the class "User", and there are 10 possible test cases, should I be adding all those 10 test cases in the testGetUserDetails() method in the UserTest class or do I write each cases in separate methods like testGetUserDetailsCaseA(), testGetUserDetailsCaseB(), testGetUserDetailsCaseC() etc etc??


    Thanks

  8. #8
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    4,807
    Mentioned
    141 Post(s)
    Tagged
    0 Thread(s)
    That is what we (the company I work for) do. Granted we name ours like so:
    when_user_details_is_admin()
    when_user_details_is_missing_name()
    etc.
    Be sure to congratulate xMog on earning April's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes


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
  •