1. What is Difference between @Injectmock and @Mock?
    @Mock creates a mock. @InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock (or @Spy) annotations into this instance.
    Note you must use @RunWith(MockitoJUnitRunner.class) to initialize these mocks and inject them (JUnit 4).With JUnit 5, you must use @ExtendWith(MockitoExtension.class).

    @RunWith(MockitoJUnitRunner.class) // JUnit 4
    // @ExtendWith(MockitoExtension.class) for JUnit 5
    public class SomeManagerTest {
    
        @InjectMocks
        private SomeManager someManager;
    
        @Mock
        private SomeDependency someDependency; // this will be injected into someManager
     
         //tests...
    }
    

  2. When should I use spy vs Mock?
    Use @Mock when you want to just test the functionality externally without actually calling that method. Use @Spy when you want to test the functionality externally + internally with the very method being called. Spy is a combination of Mock(methodInterceptors) and InjectMock(Instance of class Tested).
  3. What happens when unstubbed method called?
    Mockito will return null or primitive value or empty collection
  4. Does mockito when accepts combination of specific and generic matchers?
    No. Mockito matchers should be either generic or specific.
  5. What is BDD?
    Behaviour Driven Development (Given Scenario -> When the action happens -> Then this should be the case)

    Given 3 Items in Cart ->  When One Item gets Deleted -> Then 2 Items would be in Cart
    
  6. How to Verify whether the Service or method call has been made?
    Verify is used to check whether the call to the method is done or not.

    .
    .
     Mockito.verify(employeeDB, times(1)).getEmployeeByIdFromDB("101");
     Mockito.verify(employeeDB, never()).getEmployeesFromDB();
     Mockito.verify(employeeDB, atleast(2)).getEmployeeByIdFromDB("101");
    .
    .
    
  7. How to check the arguments passed to the method?
    ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
    verify(mock).doSomething(argument.capture());
    assertEquals("John", argument.getValue().getName());
    

    (or)

    //capturing varargs:
    ArgumentCaptor<Person> varArgs = ArgumentCaptor.forClass(Person.class);
    verify(mock).varArgMethod(varArgs.capture());
    List expected = asList(new Person("John"), new Person("Jane"));
    assertEquals(expected, varArgs.getAllValues());
    
  8. @SpringBootTest vs @runwith(springrunner.class) or @ExtendWith
    Enables spring boot features like @Autowire, @MockBean etc.. during junit testing. This is used to provide a bridge between Spring Boot test features and JUnit. Whenever we are using any Spring Boot testing features in our JUnit tests, this annotation will be required.@RunWith is an old annotation from JUnit 4 to use test runners. If you’re using JUnit 5 (Jupiter), you should use @ExtendWith to use JUnit extensions

    @SpringBootTest : This annotation is used to load complete application context for end to end integration testing.The @SpringBootTest annotation can be used when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. So this would be the annotation used while testing bootstrap class of Spring Boot Application. load application.properties and give me all the Spring Boot goodness

    We pass list of classes as parameter to @SpringBootTest whose configs are loaded from application.properties when the application is bootstrapped.

    RestWithSpringBootApplicationTests.java

    @SpringBootTest(classes = {RestWithSpringBootApplication.class, EmployeeMgmtConfig.class})
    class RestWithSpringBootApplicationTests {
      @Test
      void contextLoads() {
      }
    }
    
  9. How Methods are mocked Internally?
    Mockito works by storing and retrieving method invocation details on mocks using method interception
    When we invoke the when() method we are in fact recalling the last registered method call from that context, In our case it is Dep2Method() is saved and returned.The recorded behaviour is played back when our test invokes the mocked method again which triggers the interceptor to recall the return value we provided.In Mockito source code, we see when method does not use the parameter methodCall. But it tries to get the OngoingStubbing from an instance of MockingProgress. This OngoingStubbing is nothing but mocking context above.

     @Test
        void doIt() {
            ClassADep1.Dep2Method();
            Mockito.when("Some Blah Blah").thenReturn("Mocked!");
            assertEquals(objTarget.doIt("Sample"), "Mocked!");
        }
    
  10. What is the difference between @ExtendWith(SpringExtension.class) and @ExtendWith(MockitoExtension.class)?
    If you want to use Spring test framework features in your tests like for example @MockBean, then you have to use @ExtendWith(SpringExtension.class). It replaces the deprecated JUnit4 @RunWith(SpringJUnit4ClassRunner.class)

    When NOT involving Spring – If you just want to involve Mockito and don’t have to involve Spring, for example, when you just want to use the @Mock / @InjectMocks annotations, then you want to use @ExtendWith(MockitoExtension.class), as it doesn’t load in a bunch of unneeded Spring stuff. It replaces the deprecated JUnit4 @RunWith(MockitoJUnitRunner.class).

  11. When to use @Extendwith and @Runwith?
    If you are using Junit version < 5, so you have to use @RunWith(SpringRunner.class) or @RunWith(MockitoJUnitRunner.class) etc.If you are using Junit version = 5, so you have to use @ExtendWith(SpringExtension.class) or @ExtendWith(MockitoExtension.class) Junit4 uses *Runner.class in annotation with @RunWith

    SpringRunner.class and MockitoJunitRunner.class for Junit4
    SpringExtension.class and MockitoExtension.class for Junit5
    

What is BDD?

  Given some preconditions (Arrange) -> When an action occurs (Act) -> Then verify the output (Assert)

I.E.

  Given three items in Cart
  When one Item is deleted
  Then Two items should be left in Cart
@ExtendWith(MockitoExtension.class)
public class EmpServiceImplTest {

    @Mock
    EmployeeDB employeeDB;

    @InjectMocks
    EmpServiceImpl empServiceImpl;

    @Test
    @DisplayName("Check Employee in BDD Style")
    public void test_getEmployees_Success(){
        //Given - Employee List has only one row with List size as 1
        //When  - New Employee is added to the List
        //Then  -  Employee List should contain two rows

        //Given - Employee List has 3 Employees with List size as 3
        List<Employee> arrEmployees = new ArrayList<>();
        arrEmployees.add(new Employee("101", "Mugil"));
        arrEmployees.add(new Employee("102", "Max"));
        arrEmployees.add(new Employee("103", "Mani"));

        given(employeeDB.getEmployeesFromDB()).willReturn(arrEmployees);

        //When
        List<Employee> arrFilteredEmps = empServiceImpl.getEmployees();

        //Then - there should 3 EmployeegetEmployeeByIdFromDB
        Assertions.assertEquals(3, arrFilteredEmps.size());
    }
}
  1. @BeforeAll, @AfterAll – Runs Before and After Class and should be static
  2. @DisplayName – Displays description about the Test Method
  3. @Disabled – @Ignore in Junit 4. Disables the Test Method
  4. @Nested – Helps in grouping of similar test methods together
  5. @ParameterizedTest – Supplying more than one input for same method in row using array
  6. @ValueSource – Provides multiple paramters to same test method for ParameterizedTest
  7. @CsvSource – Provides multiple paramters to same test method for ParameterizedTest in Key Value Pair. Key is Input and Value is expected Output

AccountUtils.java

import java.io.IOException;

public class AccountUtils {

    public boolean validateAccountId(String acctNo) throws IOException {
        if (getAccountIDLength(acctNo)) {
            return true;
        } else {
            throw new IOException("Account ID is Invalid");
        }
    }

    public boolean getAccountIDLength(String acctNo)
    {
        if(acctNo.length() < 5) return false;
        if(acctNo.length() > 10) return false;
        if(!acctNo.contains("-")) return false;

        return true;
    }

    public  String getFormattedAccID(String accountNo){
        return accountNo.toUpperCase();
    }

    public String[] getBankDetails(String accountNo){
        String[] arrAccountDetails = accountNo.split("-");
        return arrAccountDetails;
    }
}

AccountUtilsTest.java

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.fail;

public class AccountUtilsTest {

    AccountUtils systemUnderTest = new AccountUtils();

    @BeforeAll
    static void init(){
        System.out.println("Initilize connection to Database");
    }

    @AfterAll
    static void destroy(){
        System.out.println("Deallocate connection to Database");
    }

    @Test
    @DisplayName("AccountID Length Validation Success")
    void test_getAccountIDLength_Success(){
        boolean expectedOutput = true;
        boolean actualOutput = systemUnderTest.getAccountIDLength("SBI-104526");

        Assertions.assertEquals(expectedOutput, actualOutput);
        Assertions.assertTrue(actualOutput);
    }

    @Test
    @Disabled
    void test_validateAccountId_Success() throws IOException {
        Assertions.assertTrue(systemUnderTest.validateAccountId("SBI-104526"));
    }

    @Test
    @DisplayName("AccountID is Invalid ")
    void test_validateAccountId_Exception(){
        Assertions.assertThrows(IOException.class, ()->{
            systemUnderTest.validateAccountId("");
        });
    }

    @Test
    @DisplayName("Account Bank Details Validation")
    void test_AccountIDForBankName_Success(){
        String[] expectedOutput = new String[]{"SBI", "104526"};
        String[] actualOutput = systemUnderTest.getBankDetails("SBI-104526");

        Assertions.assertArrayEquals(expectedOutput, actualOutput);
    }

    @Nested
    class checkValidAccountId
    {
        @ParameterizedTest
        @ValueSource(strings={"SBI", "SBI-123456789", " ", ""})
        @DisplayName("Parameterized Test AccountID Length Validation Failiure")
        void test_getAccountIDLength_Failiure(String accountId){
            Assertions.assertFalse(systemUnderTest.getAccountIDLength(accountId));
        }

        @ParameterizedTest(name="AccountID {0} formatted to {1}")
        @CsvSource(value={"sbi-123456, SBI-123456", "cbi-123456, CBI-123456"})
        @DisplayName("AccountID Format Validation")
        void getFormattedAccID_Success(String inputString, String expectedOutput){
            Assertions.assertEquals(expectedOutput, systemUnderTest.getFormattedAccID(inputString));
        }
    }
}
Junit 5 = Platform + Jupiter + Vintage 
  1. Platform = Engine + Runner + Launcher
  2. All the Class files needed for Coding Test Cases
  3. Provides Support for Junit3 and 4

Adding Dependency in pom.xml for Junit 5

JUnit 5 Platform
includes junit-jupiter-api + junit-platform-engine

<dependencies>
    [...]
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>

If you want to write and execute JUnit 3 or 4 tests via the JUnit Platform add the Vintage Engine to the dependencies

<dependencies>
    [...]
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>
Relationship Depiction Interpretation Example
Dependency A depends on B
This is a very loose relationship and so I rarely use it, but it’s good to recognize and be able to read it.
Association An A sends messages to a B
Associations imply a direct communication path. In programming terms, it means instances of A can call methods of instances of B, for example, if a B is passed to a method of an A.
Aggregation An A is made up of B
This is a part-to-whole relationship, where A is the whole and B is the part. In code, this essentially implies A has fields of type B.
Composition An A is made up of B with lifetime dependency
That is, A aggregates B, and if the A is destroyed, its B are destroyed as well.

Are Dependency Injection and Depencency are Different?
Yes, They are. The Closest one to DI is aggregation. In Aggregation, we deal with direct objects. i.e. objects which maintain a state, life-cycle, etc.
But in Dependency Injection, we focus on class level interactions. This is diverged with pure OOP practice. Actually, in DI we tend to inject stateless classes(worker classes) into some other classes. Though they look like objects they are actually just stateless classes that are being injected. And instances of that class can stand independently too.

Assume a stateless worker class called StringUtils. It can be injected into classes called NounUtils, VerbUtils, etc. And also instances of StringUtils can also exist.

Which one is Close to Dependency(Not DI)
An association almost always implies that one object has the other object as a field/property/attribute (terminology differs).

A dependency typically (but not always) implies that an object accepts another object as a method parameter, instantiates, or uses another object. A dependency is very much implied by an association.

Association --> A has-a C object (as a member variable)
Dependency --> A references B (as a method parameter or return type)
public class A {
    private C c;
    public void myMethod(B b) {
        b.callMethod();
    }
}

Simple Example of Dependency, Association, Aggregation and Composition
Dependency (references)
It means there is no conceptual link between two objects. e.g. EnrollmentService object references Student & Course objects (as method parameters or return types)

public class EnrollmentService {
    public void enroll(Student s, Course c){}
}

Association (logical relationship) It means there is almost always a link between objects (they are associated). Order object has a Customer object

public class Bank {
}

public class Employee{
}

class Association 
{
    public static void main (String[] args) 
    {
        Bank bank = new Bank("Axis");
        Employee emp = new Employee("Mani");
           
        System.out.println(emp.getEmployeeName() + " is employee of " + bank.getBankName());
    }
}

Aggregation (has-a relationship of weak degree)
Special kind of association where there is whole-part relation between two objects. they might live without each other though.

public class PlayList {
    private List<Song> songs;
}

OR

public class Computer {
    private Monitor monitor;
}

Note: the trickiest part is to distinguish aggregation from the normal association. Honestly, I think this is open to different interpretations.

Composition (has-a relationship of strong degree+ ownership or Part-Of)
Special kind of aggregation. An Apartment is composed of some Rooms. A Room cannot exist without an Apartment. when an apartment is deleted, all associated rooms are deleted as well.

public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
} 
Posted in UML.

UML Diagrams

  1. Structure Diagrams
    • Class Diagrams
    • Deployment Diagrams
  2. Behaviour Diagrams
    • Use Case Diagrams
    • Activity Diagrams
    • State Machine Diagrams
  3. Interaction Diagrams
    • Sequence Diagrams

Class Diagrams Basics

  1. Class Contains ClassName, Attributes and Operations
  2. Class Names are written in Bold or Italic if class is Abstract
  3. Attributes

     <Visibility><Name>:<Type>=<Defaultvalue><{Modifier}>
    
         
      Visibility 
        + - Public
        - - Private 
        ~ - Package
        # - Protected 	
      Name   
        Name of Variable
      Type 
        Integer, String, Boolean
      DefaultValue 
        Value by DefaultValue
      Modifier
        ReadOnly
    
  4. Operations

     <Visibility><Name>(<ParameterList>):<ReturnType>	
    
      Visibility 
        + - Public
        - - Private 
        ~ - Package
        # - Protected 	
      Name   
        Name of Operations
      ParameterList		
        List of Parameters - Comma Seperarted or Empty
      ReturnType
        Integer, String or Another Class  
    
  5. Static Elements – Static Operations and Attributes are underlined in UML Diagram

Relationships

Posted in UML.

Relationships between Classes

  1. Association
    • Composition
    • Aggregation
  2. Generalization
  3. Realization
  4. Dependency

Association(Has-A Relationship)

  1. Association is a relationship between two separate classes that establish through their objects. Each objects have their own life-cycle and there is no owner. Association can be one-to-one, one-to-many, many-to-one, many-to-many. It isn’t a “has-a” relationship and only means that the objects “know” each other

    class Bank  
    { 
        private String name;      
    
        Bank(String name){ 
            this.name = name; 
        } 
          
        public String getBankName(){ 
            return this.name; 
        } 
    }    
    
    class Employee 
    { 
        private String name; 
       
        Employee(String name){ 
            this.name = name; 
        } 
          
        public String getEmployeeName(){ 
            return this.name; 
        }  
    } 
      
    class Association  
    { 
        public static void main (String[] args)  
        { 
            Bank bank = new Bank("Axis"); 
            Employee emp = new Employee("Mani"); 
              
            System.out.println(emp.getEmployeeName() +  
                   " is employee of " + bank.getBankName()); 
        } 
    } 
    

    In above example two separate classes Bank and Employee are associated through their Objects. Bank can have many employees, So it is a one-to-many relationship.

  2. Aggregation and Composition are subsets of association meaning they are specific cases of association.Both of them conveys a has-a relationship to strong and weak degree
    1. Composition(Strong has-a relationship)
    2. Aggregation(Weak has-a relationship)
  3. has-a relationship simply means that an instance of one class has a reference to an instance of another class or an other instance of the same class
  4. Composition denotes a has-a relationship of Strong degree. Relationship among class members are strong.Classes which are grouped by Composition doesnot makes sense when interpreted seperately. I.E. when Person, Heart, Hand were seperated Heart and Hand doesnot make much sense.Objects in a composition relationship cannot, conceptually, exist in isolation. If we destroy the owner object, its members also will be destroyed with it

    public class WebPage { 
        private final PageHeader header;
        private final PageBody pageBody;
     
        public WebPage(PageHeader header, PageBody pageBody) {
            this.header = header;
            this.pageBody = pageBody;
        }
    }
     
    class PageHeader { 
        private String title;
        private String charset; 
    }
     
    class PageBody { 
        private String body;
    }
    
  5. Aggregation denotes a has-a relationship of Weak degree.Relationship among class members are weak. I.E. When trees were seperated from City Class Trees still make perfect sense and stand on it own.Objects on both sides of an aggregation relationship can exist in isolation.

    public class Team { 
        private List<Player> players = new ArrayList<>();
        public void addPlayer(Player player) {
            this.players.add(player);
            player.setTeam(this);
        }
     
        public void removePlayer(Player player) {
            this.players.remove(player);
            player.setTeam(null);
        }
    }
     
    class Player { 
        private String name;
        private int age;
     
        public void setTeam(Team team) {
            this.team = team;
        }
    }
    
  6. In UML notation, a composition is denoted by a filled diamond, while aggregation is denoted by an empty diamond, which shows their obvious difference in terms of strength of the relationship.

Composition vs Aggregation

Generalization(Is-A Relationship)

  1. In inheritance, a child of any parent can access, update, or inherit the functionality as specified inside the parent object. A child object can add its functionality to itself as well as inherit the structure and behavior of a parent object.This type of relationship collectively known as a generalization relationship.
  2. public class Vehicle 
    {    
    
    }
     
    class Truck extends Vehicle 
    {
    
    }
     
    class Boat extends Vehicle 
    {
     
    }
    

Realization(interfaces)

  1. In a realization relationship of UML, one entity denotes some responsibility which is not implemented by itself and the other entity that implements them. This relationship is mostly found in the case of interfaces.
  2. Realization is a specialized abstraction relationship between two sets of model elements, one representing a specification (the supplier) and the other represents an implementation of the latter (the client).

  3. class Hyndai implements Car {
    .
    .
    }
    

Dependency

  1. In a dependency relationship, as the name suggests, two or more elements are dependent on each other.Dependency relationships exist when classes depend on each other in such a way that a change to one class may affect the other, such as when one class accepts an instance of another class as parameter to a method.
  2. Dependency –> A references B (as a method parameter or return type)

    public class A {
        private C c;
        public void myMethod(B b) {
            b.callMethod();
        }
    }
    
  3. Dependency relationships are represented by arrows on dashed lines. Dependency represents the weakest of relationship
  4. A dependency relationship can exist when we have a Library class that manages Book objects. Since the Library class has a method that returns a Book, changes to the Book class could result in changes to the Library class (based on how Book objects are created).

    public class Library
    { 
        public Book findBook(String name) {
            //Do some book stuff.
            return new Book();
        }
    }
     
    class Book { 
        private String name;
        private String author;
    }
    
  5. A dependency typically (but not always) implies that an object accepts another object as a method parameter, instantiates, or uses another object. A dependency is very much implied by an association.
Posted in UML.
  1. Wiremock Intro?
    • Serves canned responses to particular requests (stubbing), and that captures incoming requests so that they can be checked later (verification).
    • External to application code which helps in the testing app in Dev and ST(System Testing) environment
    • Helps in testing negative Scenarios like network latency
    • Language Agnostic and production like testing
  2. How to differentiate Positive and Negative Scenarios?
    It could be done based on method(GET, POST, DELETE, PUT), Path(/employee, /success) and based on Parameter.

     GET /employee?name=mugil
           
     Method - GET
     Path   - /employee
     Params - name       
    

  3. How priority of Stub Response is selected when Paths overlap?
    Stub is lowest no in priority would be selected.

    	//Priority 1
    	wireMockServer.stubFor(get("/welcome")
    			.atPriority(1)
    			.willReturn(aResponse()
    		        .withBody("Welcome with Priority 1")));
    
    	//Priority 2
            wireMockServer.stubFor(get("/welcome")
    		.atPriority(2)
                    .willReturn(aResponse()
                    .withBody("Welcome with Priority 2")));
    

    Output

    Welcome with Priority 1
    
  4. What is advantage of using Wiremock as Standalone?
    • Less dependency on Environment
    • Useful for Load Testing
    • Can be used by non JVM environment
    • Can run remotely
  5. What are possible defects which could happen in application?
    1. Timeout
    2. Server Error
    3. Invalid Response

Irrespective of Devops tool you use the below are the generic steps which would be carried out from
code changes to deployment in environment

Build Pipeline

  1. Step 1-Preparation of Environment for Build. This includes initializing buildno, commitid, buildname which would be used internally by the devops tool
  2. Step 2-Build Script for creating artifact
  3. Step 3-Copy Script for Copying Artifact to Staging Directory. Environment Directory(Directory on which new artifact would be created after build) to Staging Directory(Directory from which artifact would be created to drop location)
  4. Step 4-Publishing Script – to publish the artifact to DROP location. This is like common place which would be refered by release pipeline

Release Pipeline

  1. From DROP location the artifact would be picked. For this Trigger should be used.
  2. Trigger should detect the availability of new release and in which branch should be checked for new release.
  3. New artifact should be pushed to Deployment Environment(Dev, Testing or Prod). For this push Command should be used
  4. There should be agent to carry out the above tasks