🖍️
Developer Note
  • Welcome
  • Git
    • Eslint & Prettier & Stylelint & Husky
  • Programming Language
    • JavaScript
      • Script Async vs Defer
      • Module
      • Const VS Let VS Var
      • Promise
      • Event Loop
      • Execution Context
      • Hoisting
      • Closure
      • Event Buddling and Capturing
      • Garbage Collection
      • This
      • Routing
      • Debounce and Throttle
      • Web Component
      • Iterator
      • Syntax
      • String
      • Array
      • Object
      • Proxy & Reflect
      • ProtoType
      • Class
      • Immutability
      • Typeof & Instanceof
      • Npm (Node package manager)
    • TypeScript
      • Utility Type
      • Type vs Interface
      • Any vs Unknown vs Never
      • Void and undefined
      • Strict Mode
      • Namespace
      • Enum
      • Module
      • Generic
    • Python
      • Local Development
      • Uv
      • Asyncio & Event loop
      • Context Manager
      • Iterator & Generator
      • Fast API
      • Pydantic & Data Class
    • Java
      • Compilation and Execution
      • Data Type
      • Enumeration
      • Data Structure
      • Try Catch
      • InputStream and OutputStream
      • Concurrent
      • Unicode Block
      • Build Tools
      • Servlet
      • Java 8
  • Coding Pattern
    • MVC vs MVVM
    • OOP vs Functional
    • Error Handling
    • MVC vs Flux
    • Imperative vs Declarative
    • Design Pattern
  • Web Communication
    • REST API
      • Web Hook
      • CORS issue
    • HTTPS
    • GraphQL
      • REST API vs GraphQL
      • Implementation (NodeJS + React)
    • Server-Sent Event
    • Web Socket
    • IP
    • Domain Name System (DNS)
  • Frontend
    • Progressive Web App (PWA)
    • Single Page & Multiple Page Application
    • Search Engine Optimiaztion (SEO)
    • Web bundling & Micro-frontend
      • Webpack
        • Using Webpack to build React Application
        • Using Webpack to build react library
      • Vite
      • Using rollup to build react library
      • Implementing micro frontend
    • Web Security
      • CSRF & Nonce
      • XSS
      • Click hijacking
    • Cypress
    • CSS
      • Core
        • Box Model
        • Inline vs Block
        • Flexbox & Grid
        • Pseudo Class
        • Position
      • Tailwind CSS
        • Shadcn
      • CSS In JS
        • Material UI
    • React
      • Core
        • Component Pattern
        • React Lazy & Suspense
        • React Portal
        • Error Boundary
        • Rendering Methods
        • Environment Variable
        • Conditional CSS
        • Memo
        • Forward Reference
        • High Order Component (HOC) & Custom Hook
        • TypeScript
      • State Management
        • Redux
        • Recoil
        • Zustand
      • Routing
        • React Router Dom
      • Data Fetching
        • Axios & Hook
        • React Query
        • Orval
      • Table
        • React Table
      • Form & Validation
        • React Hook Form
        • Zod
      • NextJS
        • Page Router
        • App Router
      • React Native
    • Angular
    • Svelte
      • Svelte Kit
  • Backend
    • Cache
      • Browser Cache
      • Web Browser Storage
      • Proxy
      • Redis
    • Rate limit
    • Monitoring
      • Logging
      • Distributed Tracing
    • Load Test
    • Encryption
    • Authentication
      • Password Protection
      • Cookie & Session
      • JSON Web Token
      • SSO
        • OAuth 2.0
        • OpenID Connect (OIDC)
        • SAML
    • Payment
      • Pre-built
      • Custom
    • File Handling
      • Upload & Download (Front-end)
      • Stream & Buffer
    • Microservice
      • API Gateway
      • Service Discovery
      • Load Balancer
      • Circuit Breaker
      • Message Broker
      • BulkHead & Zipkin
    • Elastic Search
    • Database
      • SQL
        • Group By vs Distinct
        • Index
        • N + 1 problem
        • Normalization
        • Foreign Key
        • Relationship
        • Union & Join
        • User Defined Type
      • NOSQL (MongoDB)
      • Transaction
      • Sharding
      • Lock (Concurrency Control)
    • NodeJS
      • NodeJS vs Java Spring
      • ExpressJS
      • NestJS
        • Swagger
        • Class Validator & Validation Pipe
        • Passport (Authentication)
      • Path Module
      • Database Connection
        • Integrating with MYSQL
        • Sequalize
        • Integrating with MongoDB
        • Prisma
        • MikroORM
        • Mongoose
      • Streaming
      • Worker Thread
      • Passport JS
      • JSON Web Token
      • Socket IO
      • Bull MQ
      • Pino (Logging)
      • Yeoman
    • Spring
      • Spring MVC
      • Spring REST
      • Spring Actuator
      • Aspect Oriented Programming (AOP)
      • Controller Advice
      • Filter
      • Interceptor
      • Concurrent
      • Spring Security
      • Spring Boot
      • Spring Cloud
        • Resilience 4j
      • Quartz vs Spring Batch
      • JPA and Hibernate
      • HATEOS
      • Swagger
      • Unit Test (Java Spring)
      • Unit Test (Spring boot)
  • DevOp
    • Docker
    • Kubernetes
      • Helm
    • Nginx
    • File System
    • Cloud
      • AWS
        • EC2 (Virtual Machine)
        • Network
        • IAM
          • Role-Service Binding
        • Database
        • Route 53
        • S3
        • Message Queue
        • Application Service
        • Serverless Framework
        • Data Analysis
        • Machine Learning
        • Monitoring
        • Security
      • Azure
        • Identity
        • Compute Resource
        • Networking
        • Storage
        • Monitoring
      • Google Cloud
        • IAM
          • Workload Identity Federation
        • Compute Engine
        • VPC Network
        • Storage
        • Kubernetes Engine
        • App Engine
        • Cloud function
        • Cloud Run
        • Infra as Code
        • Pub/Sub
    • Deployment Strategy
    • Jenkins
    • Examples
      • Deploy NextJS on GCP
      • Deploy Spring on Azure
      • Deploy React on Azure
  • Domain Knowledge
    • Web 3
      • Blockchain
      • Cryptocurrency
    • AI
      • Prompt
      • Chain & Agent
      • LangChain
      • Chunking
      • Search
      • Side Products
Powered by GitBook
On this page
  • Pre-Action
  • Stub vs Mock vs Spy
  • Stub vs Mock
  • Mock vs Spy
  • Mockito Method
  • doAnswer (used to mock the void type function)
  • doReturn (used to mock the return value of function)
  • Service Testing Example
  • TestServiceImpl
  • ShopServiceImpl
  • testServiceTest
  • Controller Unit Test
  • MockMvc
  • MockMvcRequestBuilders
  • MockMvcResultMatchers
  • MockMvcResultHandlers
  • Example
  • Reference

Was this helpful?

  1. Backend
  2. Spring

Unit Test (Java Spring)

Pre-Action

  • Install J Unit and Mockito dependencies

E.g: Maven

	<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>2.23.0</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-junit-jupiter</artifactId>
			<version>2.23.0</version>
			<scope>test</scope>
		</dependency>

Stub vs Mock vs Spy

Stub vs Mock

  • Stub: Initialize -> Exercise -> Verify

private class FooStub implements Foo
{
    public String bar()
    {
        return"baz";
    }
}
public class FooCollectionTest
{
    @Test
    public void test()
    {   
        //Initialize 
        FooStub newFooStub = new FooStub();
        FooCollection sut = newFooCollection();
        sut.add(newFooStub.bar());
        sut.add(newFooStub.bar());
        //Exercise and Verify
        assertEquals("bazbaz",sut.joined());
    }
}
  • Mock: Initialize -> Set up expectations -> Exercise -> Verify

public class FooCollectionTest
{    
    @Mock
    FooStub newFooStub;
    
    //Initialize
    @InjectMock
    FooCollection sut ;
    
    @Test    
    public void test()
    {   
       
        // Setup expectations
        Mockito.doReturn("baz").when(newFooStub).bar();
        
        sut.add(newFooStub.bar());
        sut.add(newFooStub.bar());
        //Exercise and Verify
        assertEquals("bazbaz",sut.joined());
    }
}

Mock vs Spy

  • Spy will actually call the real method of the class , while mock doesn't

  • Spy

@Test
public void whenCreateSpy_thenCreate() {
    List spyList = Mockito.spy(new ArrayList());
 
    spyList.add("one");
    Mockito.verify(spyList).add("one");
 
    assertEquals(1, spyList.size());
}
  • Mock

@Test
public void whenCreateMock_thenCreated() {
    List mockedList = Mockito.mock(ArrayList.class);
 
    mockedList.add("one");
    Mockito.verify(mockedList).add("one");
 
    assertEquals(0, mockedList.size());
}

Mockito Method

doAnswer (used to mock the void type function)

Mockito.doAnswer(invocation->{
    if(invocation != null && invocation.getArguments().length > 0){
        System.out.println("Test Void");
    }
    return null;
}).when(productService).test(Integer input);

doReturn (used to mock the return value of function)

 Mockito.doReturn(0).when(shopService).test(any(Integer.class));

Service Testing Example

TestServiceImpl

package com.example.demo.service.impl;

import com.example.demo.service.ShopService;
import com.example.demo.service.TestService;

public class TestServiceImpl implements TestService {
    Integer addNumber = 2;
    ShopService shopService;
    @Override
    public Integer gg(){
        return 3;
    }

    @Override
    public void testVoid(){

    }
    @Override
    public Integer test(){
        Integer num = gg();
        Integer num2 = shopService.test(10);
        return 1 + num + num2;
    }

}

ShopServiceImpl

package com.example.demo.service.impl;

import com.example.demo.service.ShopService;

public class ShopServiceImpl implements ShopService {
    @Override
    public Integer test(Integer input){
        return input;
    }
}

testServiceTest

package com.example.demo.service;

import com.example.demo.service.impl.TestServiceImpl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;


import static org.mockito.ArgumentMatchers.any;

@RunWith(MockitoJUnitRunner.class)
public class testServiceTest {

    @Mock
    private ShopService shopService;

    @InjectMocks
    private TestService testService;

      private TestService testService1;

    //Constructor
    public testServiceTest() {
        testService = new TestServiceImpl();
    }
    @Before
    public void setUp() throws Exception{
        testService1 = Mockito.spy(testService);
    }

    @Test
    public void testTest() throws Exception{
        Mockito.when(testService1.gg()).thenReturn(1);
        Mockito.doReturn(0).when(shopService).test(any(Integer.class));
        Mockito.doAnswer(invocationOnMock -> {
            if(invocationOnMock != null && invocationOnMock.getArguments().length>0){
                System.out.println("testvoid");
            }
            return null;
        }).when(testService1).testVoid();
        Integer result = testService1.test();
        Assert.assertSame(2,result);
    }

}

Controller Unit Test

MockMvc

  • Create a new MockMvc Object as a entry point, so that we can use it to call the link of API

@RunWith(MockitoJUnitRunner.class)
public class schoolControllerTest
{
    private MockMvc mockMvc;
    
    private SchoolController schoolController;
    
    @Before
    public void setUp() throws NotFoundException{
        this.mockMvc = MockMvcBuilders.standaloneSetup(schoolController).build();
    } 
}
  • Method

@Test  
public void testView() throws Exception {  
 MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/user/1"))  
            .andExpect(MockMvcResultMatchers.view().name("user/view"))  
            .andExpect(MockMvcResultMatchers.model().attributeExists("user"))  
            .andDo(MockMvcResultHandlers.print())  
            .andReturn();  
}  
  • perform: make a request to api end point

  • andExpect: verify the result whether the actual is equal to actual or not

  • andDo: to make a handling after getting the result, such as print out the response

  • andReturn: return back to MvcResult

MockMvcRequestBuilders

  • Used to create a request

  • Methods

MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的MockHttpServletRequestBuilder;如get(/user/{id}, 1L);

MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables):同get类似,但是是POST方法;

MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables):同get类似,但是是PUT方法;

MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) :同get类似,但是是DELETE方法;

MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables):同get类似,但是是OPTIONS方法;

MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables): 提供自己的Http请求方法及uri模板和uri变量,如上API都是委托给这个API;

MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables):提供文件上传方式的请求,得到MockMultipartHttpServletRequestBuilder;

RequestBuilder asyncDispatch(final MvcResult mvcResult):创建一个从启动异步处理的请求的MvcResult进行异步分派的RequestBuilder;

MockMvcResultMatchers

  • used to match the result of api end point , such as content-type, https status, return value

  • Methods

HandlerResultMatchers handler():请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器;

RequestResultMatchers request():得到RequestResultMatchers验证器;

ModelResultMatchers model():得到模型验证器;

ViewResultMatchers view():得到视图验证器;

FlashAttributeResultMatchers flash():得到Flash属性验证;

StatusResultMatchers status():得到响应状态验证器;

HeaderResultMatchers header():得到响应Header验证器;

CookieResultMatchers cookie():得到响应Cookie验证器;

ContentResultMatchers content():得到响应内容验证器;

JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath  (String expression, Matcher matcher):得到Json表达式验证器;

XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args):得到Xpath表达式验证器;

ResultMatcher forwardedUrl(final String expectedUrl):验证处理完请求后转发的url(绝对匹配);

ResultMatcher forwardedUrlPattern(final String urlPattern):验证处理完请求后转发的url(Ant风格模式匹配,@since spring4);

ResultMatcher redirectedUrl(final String expectedUrl):验证处理完请求后重定向的url(绝对匹配);

ResultMatcher redirectedUrlPattern(final String expectedUrl):验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4)

MockMvcResultHandlers

  • used to print the whole of the response of api end point

Example

@Test
public void getInventoryByProductCodeTest1() throws Exception
{
  mockMvc.perform(MockMvcRequestBuilders.get("/api/getSchool"))
  .andExpect(MockMvcResultMatchers.status().isOk()) // Check the http status
  .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) // check the content type
  .andExpect(MockMvcResultMatchers.jsonPath("studentName").value("Tom")); // check the result
}

Reference

PreviousSwaggerNextUnit Test (Spring boot)

Last updated 4 years ago

Was this helpful?

https://www.jianshu.com/p/91045b0415f0