0% found this document useful (0 votes)
7 views

Unit Test1

The document outlines best practices for unit testing, including naming conventions, the use of test doubles, and the importance of test coverage. It emphasizes the need for clear test case selection based on input combinations and boundary conditions, and discusses the use of Mockito for mocking and verifying interactions. Additionally, it introduces Test-Driven Development (TDD) as a methodology for writing tests before production code to ensure reliability and adherence to requirements.

Uploaded by

ebinjoy999
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Unit Test1

The document outlines best practices for unit testing, including naming conventions, the use of test doubles, and the importance of test coverage. It emphasizes the need for clear test case selection based on input combinations and boundary conditions, and discusses the use of Mockito for mocking and verifying interactions. Additionally, it introduces Test-Driven Development (TDD) as a methodology for writing tests before production code to ensure reliability and adherence to requirements.

Uploaded by

ebinjoy999
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Unit test function name -

<unitOfWork>_<stateUnderTest>_<expectedBehavior>
isOverlap_interval1BeforeInterval2_falseReturned

@Nullable - implicitly tells that my function can be nullable in argument or return value
No need for a null case test in most cases.

How to choose test cases:


● 100% line coverage is necessary, but not sufficient to ensure good coverage of SUT functionality
● Identify different groups of input combinations corresponding to different states
● Write at least one test case for a representative of each group
● Write test cases for boundary conditions between different groups of inputs

Test Double
1. Fake -Functional substitution for real units (optimized for tests) - fake -optimized for tests.
2. Stubs - returns predefined data (like API results) - predefined data, like network data
3. Mock (record interaction during the test) - record interaction with itself

When creating fake test double classes under Test class make sure it ends with ‘Td’

If the test is not passed, there will be mainly 3 reasons for that
● There is an issue in the test code.
● Bug in production code.
● A wrong requirement is given.

Avid following(flaky test)


1. Avoid functional static codes, difficult to test, simple ones are ok (Static dependencies are not visible at the
level of the public apis)
2. Singleton: When run tests simultaneously, some tests will fail, bcoz static state is shared among tests and
cause fail,. Usually, JUnit will create a different instance for each test.

You used Test Doubles, the classes(LoginHttpEndpointSyncTd) you use in the test class to substitute external
dependencies. But this is only using 30% of java developers others using mockito frameworks.
--------------------------------------------------------------------------------------------------------------------------------------
Mockito
Verify() -> Mockito assertion asserts that some method is called no. of times.
Eg: mLoginHttpEndpointSyncMock should call loginSync() exactly one time and capture argument.
​ ​mLoginHttpEndpointSyncMock​, ​times​(​1​)).loginSync(​ac​.capture()​, ​ac​.capture())​;
verify(

doAnswer() ->
doAnswer(​new A ​ nswer​() {
​@Override
​public O ​ bject ​answer​(​InvocationOnMock invocation) ​ ​throws ​Throwable ​{
​ bject[
O ​ ] ​args ​= ​invocation.
​ getArguments()​;
C​ allback callback ​= (​Callback) ​ a ​ rgs​[​1​]​;
c ​ allback​.onGetCartItemsFailed(G ​ etCartItemsHttpEndpoint​.​FailReason. ​ ​NETWORK_ERROR)
​ ;

r ​ eturn null​;
​}
}).when(m ​ GetCartItemsHttpEndpointMock) ​ .getCartItems(anyInt()​, ​any(​Callback​.​class)​ );

when() -> Action when some method is called with some value
when​(​mLoginHttpEndpointSyncMock​.loginSync(​any(
​ ​String​.​class​)​, ​any​(​String​.​class​)))
.thenReturn(​new
LoginHttpEndpointSync​.EndpointResult(​LoginHttpEndpointSync​.​EndpointResultStatus​.​SUCCESS​, ​AUTH_TOKEN)
​ )​;

doThrow() -> Exception thws when some method is called with some value
doThrow​(​new ​NetworkErrorException())
​ ​String​.​class​)​, ​any​(S
.when(​mLoginHttpEndpointSyncMock​).loginSync(​any( ​ tring​.​class​))​;

--------------------------------------------------------------------------------------------------------------------------------------
Object Vs Data Structures

Data structures ->


expose data
Instantiate by another data structures and objects whenever needed.
Test implicitly when you test the object those use them.
No unit test need
No test doubles
Object ->
expose behavior
hide internal implementation details
objects have another obj dependency that should be injected from outside.
Needed to be unit tested explicitly
Eligible to be substituted Test doubles

Check the PDF resource.


Robert.C, Clean code

Mature programmers know​ that the idea that ​everything is an object is a myth

--------------------------------------------------------------------------------------------------------------------------------------
Structure

--------------------------------------------------------------------------------------------------------------------------------------
Without Mockito Annotation

public class ​LoginUseCaseSyncTest ​{


​LoginHttpEndpointSync ​mLoginHttpEndpointSyncMock​;
​AuthTokenCache ​mAuthTokenCacheMock​;
​EventBusPoster ​mEventBusPosterMock​;

​@Before
​public void ​setup​() ​throws ​Exception ​{
​mLoginHttpEndpointSyncMock ​= ​mock​(​LoginHttpEndpointSync​.​class​)​;
​mAuthTokenCacheMock ​= ​mock( ​ ​AuthTokenCache​.​class​)​;
​ ​EventBusPoster​.​class​)​;
​mEventBusPosterMock ​= ​mock(

With Mockito Annotation

@RunWith​(​MockitoJUnitRunner​.​class​)
public class ​LoginUseCaseSyncTest ​{

​@Mock L ​ oginHttpEndpointSync ​mLoginHttpEndpointSyncMock​;


​@Mock A ​ uthTokenCache ​mAuthTokenCacheMock​;
​@Mock E ​ ventBusPoster ​mEventBusPosterMock​;

​@Before
​public void ​setup​() ​throws ​Exception ​{
​SUT ​= ​new ​LoginUseCaseSync(​mLoginHttpEndpointSyncMock​, ​mAuthTokenCacheMock​, m
​ EventBusPosterMock​)​;
​success()​;
​ }

--------------------------------------------------------------------------------------------------------------------------------------
Mockito considerations
1. A matter of personal preference (Mockito / Test doubles)
2. More Mockito more complexity
3. Not trivially simple with Mockito then fallback to the test doubles.

----------------------------------- Test Template ---------------------------------- Add under studio settings

JUNIT -test class

import org.junit.*;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;

import static org.hamcrest.CoreMatchers.*;


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class ${NAME} {

// region constants

// endregion constants

//region helper fields

//endregion helper fields

${CLASS_NAME} SUT;
@Before
public void setup() throws Exception {
SUT = new ${CLASS_NAME} ();
${BODY}
}

//region helper methods

//endregion helper methods

//region for helper classes

//endregion for helper classes


}
JUNIT -test mesthod
@org.junit.Test
public void ${NAME}() {
//Arrange
//Act
//Assert
${BODY}
}

--------------------------------------------------------------------------------------------------------------------------------------

TDD - Test-driven development

Write the test before the production code


- Help to write a test without seeing internal implementation based on the requirement
- Can’t write a reliable unit test, if the same person writes the test after wrote the production code.
Video 32

All tests up-front: - First TDD technique


● Create an empty class for SUT
● Write all the required tests You can expand SUT's public API to make the tests compile
● You can't write the internal implementation of SUT
● Write the internal implementation of the SUT
● Run the tests a note here.
● Pass

You might also like