Challenges with UI/Service testing
- Complete application setup required along with external dependencies
- Root cause analysis takes more time as the analysis require from UI, BD & Code
- Method/group of methods
- Easy to debug
- Fast
Java 8 - Junit5
Junit
- Assert an Exception
- @Test(expected = IllegalArgumentException.class)
-
Vocabulary
- SUT - SystemUnderTest is the code to write unit tests for
- Stub
- Maintenance overhead when ever we add new methods to original class
- Useful for simple scenarios only
- Mock
Mockito
- <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency> - Key classesMockitoBDDMockitoMatchersCoreMatchers
- Mock()
- Dynamic Stub & provides much more functionality than Stubs
- Stubbing a method
- when(mock.method("param")).thenReturn(value);
- Return multiple values with Method stubbing
- when(mock.method("param")).thenReturn(1).thenReturn(3);
- Argument Matchers
- when(mock.method(anyInt())).thenReturn(1).thenReturn(3)
- any()
- Exception
- when(mock.method(anyInt())).thenThrow(new RuntimeException("asdf"))
- BDD Style(Behavior Driven Development)
- Given-When-Then(Setup-actual method call-assert
- given(mock.method(anyInt())).willReturn(1)
- Verify Calls
- verify(mock).deleteTodo("param")
- Verify method is not called
- verify(mock, never()).deleteTodo("param")
- #times called
- verify(mock, times(1)).deleteTodo("param")
- verify(mock, atLeast(1)).deleteTodo("param")
- Capture an argument passed
- then(mock).should().deleteTodo("param")
- Declare an argument Captor
ArugumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class); - Declare an argument Captor on specific method call
then(mock).should().deleteTodo(stringArgumentCaptor) - Capture the argument
assertThat(stringArgumentCaptor.getValue(),is("Learn to Dance"));
assertThat(stringArgumentCaptor.getAllValues().size(),is(2));
Hamcrest
- Readable assers
- assertThat(scores, hasSize(4))
- assertThat("", isEmptyString)
- @Mock
- Similar to Autowire annotations that creates mock for the Class type
- This requires specific kind of runner to autowire it. -> RunWith(MockitoJUnitRunner.class)
- @InjectMocks
- Automatically inject the dependencies that constructor dependencies
- @RunWith(MockitoJUnitRunner.class)
- @Captor
- Argument Captor eg: ArgumentCaptor<String> stringArgumentCaptor
- Creates captor of particular type
Rules
- 2 Junit runners is not possible
- Rules is alternative to multiple runners
- Rule is run before and after the test
- @Rule
public MockitoRule mockitoRule MockitoJUnit.rule()
We an remove the RunWith annotation
Spy
- It creates a new copy of the class with all functionality where one can override specific methods
- eg: List arrayListSpy = spy(ArrayList.class);
stub(arrayListSpy.size()).toReturn(5); - Verify that a method is called or not called
verify(arrayListSpy).add("Dummy");
PowerMock
- Mock Limitations
- Final classes
- Static methods
- final methods
- equals & hashcode
- Mock Static methods & Constructors
- Specify runner
- @RunWith(PowerMockRunner.class)
@PrepareForTest(UtilityClass.class) - Initiatlize the utilityclass that has Static method
- PowerMockito.mockStatic(UtilityClass.class)
when (UtilityClass.staticmethod(anyInt)).thenReturn(100); - Mock Private methods
- int i = Whitebox.invokeMethod(systemUnderTest,"private method to be invoked");
- Mock Constructor
- @RunWith(PowerMockRunner.class)
@PrepareForTest(UtilityClass.class) - PowerMockito.whenNew(ArrayList.class).withAnyArguments().thenReturn(mockList)
int size = systemUnderTest.methodUsingAnArrayListConstructor();
- Testing a method or group of methods
- assertEquals("","");
SonarQube
- Facilitates continuous code inspection
- Components
- Webserver
- Searchserver
- Powered by elastic search
- Compute engine
SonarScanner
- Standalone progra that scans the code and submits report to server
No comments:
Post a Comment