简体   繁体   中英

OOP Unit-testing using Stub, verify and mock (Mockito): WHITE-BOX Approach

I am learning about OOP unit testing using stubs, verify and mock using white-box approach.
The knowledge I have about them is:

  • stub provides the fake input (or gets fake input?)
  • mock creates the object of that class
  • verify verifies if the outputting is been done correctly.

According to this, I have got one example (Pseudocode) below:

Its a submodule changeAddress where it imports the objects inUser , inDialogBox , inValidator from User , DialogBox , Validator classes respectively.

Submodule changeAddress
Imports: inUser (User), inDialogBox (DialogBox), inValidator (Validator)
Exports: nothing
Algorithm:

IF inUser.loggedIn THEN
    newAddress = inDialogBox.getAddress
    IF inValidator.validAddress <-- newAddress THEN
        inUser.setAddress <-- newAddress
    ELSE
        inDialogBox.message <-- "Invalid address"
    ENDIF
ElSE
   inDialogBox.message <-- "Not logged in"
ENDIF

For this example here,

  • what will be the submodules called by changeAddress that should be stubbed and verified?
  • How many test cases will this submodule require?
    Ans :I guess this submodule requires 3 test cases, as there are 3 outputs? (not sure)

So far, I got my testcode (Using JUnit) something like below (Assuming 3 test cases ):

@Test
public void testChangeAddress() 
{
    User inUser = mock(User.class);
    DialogBox inDialogBox = mock(DialogBox.class);
    Validator inValidator = mock(Validator.class);


    //1st test case when loggedin() is true aswell as the validAddress() is true
    when(inUser.loggedIn()).thenReturn(true);     // STUB
    when(inDialogBox.getAddress()).thenReturn("Test address");  // STUB
    when(inUser.setAddress("Test address")).thenReturn(true);   // STUB
    changeAddress(inUser, inDialogBox, inValidator);          
    verify(inUser).setAddress("Test address");         //VERIFY


    //2nd test case when loggedin()is false
    when(inUser.loggedIn()).thenReturn(false);      // STUB
    changeAddress(inUser, inDialogBox, inValidator); 
    verify(inDialogBox).message("Not logged in");   //VERIFY


    //3rd test case when loggedin() is true but validAddress() is false
    when(inUser.loggedIn()).thenReturn(true);    // STUB                    
    when(inDialogBox.getAddress()).thenReturn("Test address");      // STUB
    when(inUser.setAddress("Test address")).thenReturn(false);      // STUB
    changeAddress(inUser, inDialogBox, inValidator);
    verify(inDalogBox).message("Invalid address");      //VERIFY
}   

I am not sure whether I am in a right path or not?

In this example, I suppose that the method to test (changeAddress) is defined in the class ClassToTest.

ClassToTest is using three objects in changeAddress(): the goal is to do the tests independently from the implementation of these 3 objects: that's why we mock them.

Below is an example of how it could be done:

public class MyTest {
    private User inUser;
    private DialogBox inDialogBox;
    private Validator inValidator;
    private ClassToTest classToTest;

    @Before
    public void setup() {
        inUser = mock(User.class);
        inDialogBox = mock(DialogBox.class);
        inValidator = mock(Validator.class);

        classToTest = new ClassToTest(inUser, inDialogBox, inValidator);
    }

    @Test
    //1st test case when loggedin() is true aswell as the validAddress() is true
    public void testChangeAddressWithValidAddress() {
        when(inUser.loggedIn()).thenReturn(true);     // STUB
        when(inDialogBox.getAddress()).thenReturn("Test address");  // STUB
        when(inUser.setAddress("Test address")).thenReturn(true);   // STUB
        classToTest.changeAddress(inUser, inDialogBox, inValidator);          
        verify(inUser).setAddress("Test address");         //VERIFY
    }

    @Test
    //2nd test case when loggedin()is false
    public void testChangeAddressWhenInvalidLogin() {
        when(inUser.loggedIn()).thenReturn(false);      // STUB
        classToTest.changeAddress(inUser, inDialogBox, inValidator); 
        verify(inDialogBox).message("Not logged in");   //VERIFY
    }

    @Test
    //3rd test case when loggedin() is true but validAddress() is false
    public void testChangeAddressWhenValidLoginAndInvalidAddress() {
        when(inUser.loggedIn()).thenReturn(true);    // STUB                    
        when(inDialogBox.getAddress()).thenReturn("Test address");      // STUB
        when(inUser.setAddress("Test address")).thenReturn(false);      // STUB
        classToTest.changeAddress(inUser, inDialogBox, inValidator);
        verify(inDalogBox).message("Invalid address");      //VERIFY
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM