Unit Test Notes

Posted by shawngoldw on Thu, 16 May 2019 07:41:10 +0200

Unit Test Notes

Tags (space delimited): TestNg mockito

Learning Links
Mockito Official Documentation
Geek College
TestNg
Mockito Chinese Tutorial

Mockito usage scenarios

We often encounter classes that have a lot of dependencies to test, and these dependent classes/objects/resources have other dependencies, thus forming a large dependency tree. It is difficult to build such dependencies completely in the environment of unit testing.

Basic Use

    @Test
    public void test() {
        ObjectB objectB = mock(ObjectB.class);
        ObjectA objectA = new ObjectA();
        objectA.setPwString("testString");
        when(objectB.getObjectA()).thenReturn(objectA);

        ObjectA actucalA = objectB.getObjectA();
        assertEquals(objectA, actucalA);
    }

Note that MockitoAnnotations.initMocks(this) is required when using annotation fast Mocks; Reference 2.5

Parameter Matching

You can write exact values or use any() when matching method parameters

    when(templateDAO.findAll(any(TemplateSpecification.class))).thenThrow(new 
        DataAccessException("query template failed") {
            private static final long serialVersionUID = -6784264998739312988L;
    });
    when(templateDAO.findAll(any(TemplateSpecification.class))).thenThrow(new
        DataAccessException("query template failed") {
    }); 
  • Note here that once a matcher is used for a parameter, the subsequent parameters must match
  • You can customize parameter matching yourself

The difference between doReturn().when() and when().doReturn()

Here you need to note the difference between when().doReturn and doReturn().when().

  • doReturn().when() does not really call the method
  • when().doReturn() does not call a method when the monitoring object is a full mock object (because the mock is a dummy object), but it does call the method when the object is spy
  • When the return value of the calling method is empty, only doReturn().when().method() can be used.

Validation Exception

Code Validation

    @Rule
    public ExpectedException expectedEx = ExpectedException.none(); 
    //...
    expectedEx.expect(CannotUploadTemplateException.class);
    expectedEx.expectMessage("Template Rejected"); 
    expectedEx.expect(CannotUploadTemplateException.class);
    expectedEx.expectMessage("Template Rejected"); 

Use comments to validate exceptions

    @Test(expected = RuntimeException.class)
    public void doThrow_when(){
        List list = mock(List.class);
        doThrow(new RuntimeException()).when(list).add(1);
        list.add(1);
    }

Spy Detection Object

spy is a technology that can detect real objects, can monitor methods and set object behavior, so we need to pay attention to the difference between doReturn().when() and when().doReturn(), which is a kind of half-mock object that can be understood as a real and virtual object.

    @Test
    public void test() {
        ObjectB objectB = spy(new ObjectB());
        ObjectA objectA = new ObjectA();
        objectA.setPwString("testString");
        when(objectB.getObjectA()).thenReturn(objectA);

        ObjectA actucalA = objectB.getObjectA();
        assertEquals(objectA, actucalA);
        //Here getValue() calls the actual method and the return value is "hello world"
        assertEquals("hello world", objectB.getValue());
    }

Reset Mock

     @Test
    public void reset_mock(){
        List list = mock(List.class);
        when(list.size()).thenReturn(10);
        list.add(1);
        assertEquals(10,list.size());
        //Reset mock, clear all interactions and presets
        reset(list);
        assertEquals(0,list.size());
    }

Continuous calls

    @Test(expected = RuntimeException.class)
    public void consecutive_calls(){
        //Simulate continuous calls to return expected values, if separate, only the last valid
        when(mockList.get(0)).thenReturn(0);
        when(mockList.get(0)).thenReturn(1);
        when(mockList.get(0)).thenReturn(2);
        when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException());
        assertEquals(2,mockList.get(0));
        assertEquals(2,mockList.get(0));
        assertEquals(0,mockList.get(1));
        assertEquals(1,mockList.get(1));
        //The third or more calls throw an exception
        mockList.get(1);
    }

Verify execution order

Reference 2.16 for details

Ensure that no interaction occurs on the simulation object

Reference 2.17 for details

Find redundant interactions (i.e., unauthenticated)

Reference 2.18 for details