SpringBoot项目中单元测试与集成测试的应用

测试分类

单元测试->集成测试->系统测试->验收测试

  1. 单元测试

    单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。一个单元可能是单个程序、类、对象、方法等。

    测试阶段:编码后或编码前(测试驱动开发TDD)

    测试对象:最小模块(Java-类)

    测试内容:模块接口测试、局部数据结构、路径测试、错误处理测试、边界测试

    模块接口测试:对通过被测模块的数据流进行测试。包括参数表、调用子模块的参数、全程数据、文件输入/输出操作等

    局部数据结构:数据类型说明、初始化、缺省值、上溢下溢的地址等

    路径测试:对每一条独立执行路径测试,保证每条语句至少执行一次

    错误处理测试:检查模块的错误处理功能是否包含有错误或缺陷。是否拒绝不合理的输入、输出的报错信息是否难以理解、是否对错误定位有误、 是否出错原因有误、报错代码处理执行之前,是否已引起系统报错

    测试人员:开发人员

    测试方法:白盒测试(基本路径测试、语句覆盖、条件覆盖、判定覆盖、判定条件覆盖、条件组合覆盖、路径覆盖等)

    单测目的:

    • 提高代码质量。之前在做测试时候,在项目启动后,通过Swagger或Postman访问接口进行测试,修改代码之后每次都要重新启动,耗时较长

    • 方便重构。重构之后如果不确定代码的正确性,可以走一遍单元测试做参考

    • 开发阶段排除Bug的例子:调度编辑功能,在ApplicationService层实现逻辑是参数校验、调度删除、调度新增;其中,在新增时候也有做校验,且校验失败时候直接抛出异常;导致我在新增正常调度成功后,编辑错误数据,删除成功了,但重新添加时候失败;详细测试数据见Spring Boot项目单元测试及集成测试的应用单元的2.2 Application-Service层 示例

  2. 集成测试

    集成测试是在单元测试的基础上,将所有已通过单元测试的模块按照概要设计的要求组装为子系统或系统,并进行测试的过程。目标是把通过了单元测试的模块拿来,构造一个在设计中所描述的程序结构,应当避免一次性的集成(除非软件规模很小),而采用增量集成。

    测试阶段:单元测试通过后

    测试对象:模块间的接口

    测试内容:模块之间数据传输、模块之间功能冲突、模块组装功能正确性、全局数据结构、单模块缺陷对系统的影响

    测试人员:开发人员

    测试方法:白盒测试+黑盒测试

  3. 系统测试

    测试阶段:集成测试通过后

    测试对象:整个系统

    测试内容:功能、界面、可靠性、易用性、性能、兼容性、安全性等

    测试人员:测试人员

    测试方法:黑盒测试

  4. 验收测试

    验收测试是部署软件之前的最后一个测试操作。它是技术测试的最后一个阶段,也称为交付测试。验收测试的目的是确保软件准备就绪,按照项目合同、任务书、双方约定的验收依据文档,向软件购买都展示该软件系统满足原始需求。

    测试阶段:系统测试通过后

    测试对象:整个系统

    测试内容:同系统测试

    测试人员:需求方或最终用户

    测试方法:黑盒测试

    测试阶段对比图如下:

    集成测试单元测试系统测试验收测试
    测试阶段单元测试通过后编码后或编码前集成测试通过后系统测试通过后
    测试对象模块间的接口最小模块整个系统整个系统
    测试内容模块之间数据传输、模块之间功能冲突、 模块组装功能正确性、全局数据结构、单模块缺陷对系统的影响模块接口测试、局部数据结构、路径测试、错误处理测试、边界测试功能、界面、可靠性、易用性、性能、兼容性、安全性等同系统测试
    测试人员开发人员开发人员测试人员需求方或最终用户
    测试方法白盒测试+黑盒测试白盒测试黑盒测试黑盒测试

单元测试

  1. Junit

    手册:JUnit API

    常用注解:

    @BeforeClass: 在所有测试方法执行前执行一次,一般在其中写上整体初始化的代码

    public class Example {
        @BeforeClass 
        public static void onlyOnce() {
           ...
        }
        @Test 
        public void one() {
           ...
        }
        @Test 
        public void two() {
           ...
        }
     }

    @Before:在每个方法测试前执行,一般用来初始化方法

     public class Example {
        List empty;
        @Before 
        public void initialize() {
           empty= new ArrayList();
        }
        @Test 
        public void size() {
           ...
        }
        @Test
        public void remove() {
           ...
        }
     }

    @AfterClass:在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码

    public class Example {
        private static DatabaseConnection database;
        @BeforeClass 
        public static void login() {
              database= ...;
        }
        @Test 
        public void something() {
              ...
        }
        @Test 
        public void somethingElse() {
              ...
        }
        @AfterClass 
        public static void logout() {
              database.logout();
        }
     }

    @After:在每个测试方法执行后,在方法执行完成后要做的事情

    public class Example {
        File output;
        @Before 
        public void createOutputFile() {
              output= new File(...);
        }
        @Test 
        public void something() {
              ...
        }
        @After 
        public void deleteOutputFile() {
              output.delete();
        }
     }

    @Test:编写一般测试用例。支持两个可选参数,用于异常测试和限制测试执行时间

    public class Example {
        @Test
        public void method() {
           org.junit.Assert.assertTrue( new ArrayList().isEmpty() );
        }
     }

    @Test(expected = Exception.class) :测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败

        @Test(expected=IndexOutOfBoundsException.class)
        public void outOfBounds() {
            new ArrayList<Object>().get(1);
        }

    @Test(timeout = m):测试方法花费的时间超过指定的时间m毫秒后,将测试失败

        @Test(timeout=100)
        public void infinity() {
            while(true);
        }

    @Ignore("not ready yet"):执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类

     @Ignore 
     public class IgnoreMe {
         @Test 
         public void test1() { ... }
         @Test 
         public void test2() { ... }
     }
  2. Mockito

    Mock测试即在测试过程中,对于一些不容易构造的,与本次单元测试关系不大但又有上下文依赖关系的对象,用一个虚拟的对象(Mock对象)来模拟,以便单元测试能够进行。Mockito是Java单元测试的mock开源框架。

    手册:mockito-core 3.11.2 javadoc (org.mockito)

    常用方法:

    mock对象

    @BeforeEach
    void init() {
        scheduler = mock(Scheduler.class);
        scheduleService = new ScheduleServiceImpl(scheduler);
    }

    参数匹配

    anyInt()、anyLong()、anyFloat()、anyDouble(),匹配任意xx类型数据

    @Test
    void testMoc(){
        ArrayList test = mock(ArrayList.class);
        when(test.get(anyInt())).thenReturn("mock argumentMatcher");
        System.out.println(test.get(0));
    }

    设置对象调用的预期返回值

    when(condition).thenReturn(value1); 当满足when中条件时候,返回value1;当不满足时候,返回null

    when(condition).thenReturn(value1).thenReturn(value2); 当满足when中条件时候,第一次返回value1,第n(n>1且∈N*)次返回value2

    when(condition).thenReturn(value1)...thenReturn(valuen); 当满足when中条件时候,第一次返回value1,第二次返回value2...第n(n>1且∈N*)次返回valuen

    doReturn().when().someMethod(); 与thenReturn()的区别是不会调用真实方法

    示例如下:

    当满足when中条件时候,返回value1:

    @Test
    void mockitoMethodWhenThen(){
        ArrayList mockList = mock(ArrayList.class);
        //参数匹配(when中条件不满足时候,renturn null)
        when(mockList.get(anyInt())).thenReturn("mock argumentMatcher");
        System.out.println(mockList.get(0));
    }

    当不满足条件时候,返回null:

    @Test
    void mockitoMethodWhenThen(){
        ArrayList mockList = mock(ArrayList.class);
        //参数匹配(when中条件不满足时候,renturn null)
        when(mockList.get(1)).thenReturn("mock argumentMatcher");
        System.out.println(mockList.get(0));
    }

    当满足when中条件时候,第一次返回value1,第n次(n>1且∈N*)返回value2:

    @Test
        void mockitoMethodWhenThen(){
            ArrayList mockList = mock(ArrayList.class);
            //参数匹配(when中条件不满足时候,renturn null)
            when(mockList.get(anyInt())).thenReturn("First trigger").thenReturn("Second trigger").thenReturn("Third trigger");
            System.out.println(mockList.get(0));
            System.out.println(mockList.get(1));
            System.out.println(mockList.get(2));
            System.out.println(mockList.get(2));
            System.out.println(mockList.get(3));
        }

    @Test
    void mockitoMethodDoReturn() {
        ArrayList mockList = mock(ArrayList.class);
        mockList.add(1);
        doReturn(mockList.add(2)).when(mockList).add(3);
        mockList.add(3);
        assertThat(mockList.get(2)).isEqualTo(2);
    }

    API如下所示:

    /**
     * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.
     * <p>
     * Simply put: "<b>When</b> the x method is called <b>then</b> return y".
     *
     * <p>
     * Examples:
     *
     * <pre class="code"><code class="java">
     * <b>when</b>(mock.someMethod()).<b>thenReturn</b>(10);
     *
     * //you can use flexible argument matchers, e.g:
     * when(mock.someMethod(<b>anyString()</b>)).thenReturn(10);
     *
     * //setting exception to be thrown:
     * when(mock.someMethod("some arg")).thenThrow(new RuntimeException());
     *
     * //you can set different behavior for consecutive method calls.
     * //Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
     * when(mock.someMethod("some arg"))
     *  .thenThrow(new RuntimeException())
     *  .thenReturn("foo");
     *
     * //Alternative, shorter version for consecutive stubbing:
     * when(mock.someMethod("some arg"))
     *  .thenReturn("one", "two");
     * //is the same as:
     * when(mock.someMethod("some arg"))
     *  .thenReturn("one")
     *  .thenReturn("two");
     *
     * //shorter version for consecutive method calls throwing exceptions:
     * when(mock.someMethod("some arg"))
     *  .thenThrow(new RuntimeException(), new NullPointerException();
     *
     * </code></pre>
     *
     * For stubbing void methods with throwables see: {@link Mockito#doThrow(Throwable...)}
     * <p>
     * Stubbing can be overridden: for example common stubbing can go to fixture
     * setup but the test methods can override it.
     * Please note that overridding stubbing is a potential code smell that points out too much stubbing.
     * <p>
     * Once stubbed, the method will always return stubbed value regardless
     * of how many times it is called.
     * <p>
     * Last stubbing is more important - when you stubbed the same method with
     * the same arguments many times.
     * <p>
     * Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b>.
     * Let's say you've stubbed <code>foo.bar()</code>.
     * If your code cares what <code>foo.bar()</code> returns then something else breaks(often before even <code>verify()</code> gets executed).
     * If your code doesn't care what <code>get(0)</code> returns then it should not be stubbed.
     *
     * <p>
     * See examples in javadoc for {@link Mockito} class
     * @param methodCall method to be stubbed
     * @return OngoingStubbing object used to stub fluently.
     *         <strong>Do not</strong> create a reference to this returned object.
     */
    @CheckReturnValue
    public static <T> OngoingStubbing<T> when(T methodCall) {
        return MOCKITO_CORE.when(methodCall);
    }
    /**
     * Sets a return value to be returned when the method is called. E.g:
     * <pre class="code"><code class="java">
     * when(mock.someMethod()).thenReturn(10);
     * </code></pre>
     *
     * See examples in javadoc for {@link Mockito#when}
     *
     * @param value return value
     *
     * @return object that allows stubbing consecutive calls
     */
    OngoingStubbing<T> thenReturn(T value);
    /**
     * Sets consecutive return values to be returned when the method is called. E.g:
     * <pre class="code"><code class="java">
     * when(mock.someMethod()).thenReturn(1, 2, 3);
     * </code></pre>
     *
     * Last return value in the sequence (in example: 3) determines the behavior of further consecutive calls.
     * <p>
     * See examples in javadoc for {@link Mockito#when}
     *
     * @param value first return value
     * @param values next return values
     *
     * @return object that allows stubbing consecutive calls
     */
    // Additional method helps users of JDK7+ to hide heap pollution / unchecked generics array
    // creation warnings (on call site)
    @SuppressWarnings({"unchecked", "varargs"})
    OngoingStubbing<T> thenReturn(T value, T... values);

    验证调用次数

    verify(T mock);

    verify(T mock, VerificationMode mode);

    @Test
    void mockitoMethodVerify(){
        ArrayList mockList = mock(ArrayList.class);
        //验证方法是否被调用及执行次数
        mockList.add(1);
        verify(mockList).add(1);
        mockList.add(1);
        mockList.add(2);
        verify(mockList,times(2)).add(1);
        verify(mockList,never()).add(3);
        verify(mockList,atLeastOnce()).add(1);
        verify(mockList,atLeast(2)).add(1);
        verify(mockList,atMostOnce()).add(2);
        verify(mockList,atMost(2)).add(1);
    }

    @Test
        void mockitoMethodVerify(){
            ArrayList mockList = mock(ArrayList.class);
            //验证方法是否被调用及执行次数
            mockList.add(1);
            mockList.add(1);
            verify(mockList,atLeast(3)).add(1);
        }

    API如下所示:

    /**
     * Verifies certain behavior <b>happened once</b>.
     * <p>
     * Alias to <code>verify(mock, times(1))</code> E.g:
     * <pre class="code"><code class="java">
     *   verify(mock).someMethod("some arg");
     * </code></pre>
     * Above is equivalent to:
     * <pre class="code"><code class="java">
     *   verify(mock, times(1)).someMethod("some arg");
     * </code></pre>
     * <p>
     * Arguments passed are compared using <code>equals()</code> method.
     * Read about {@link ArgumentCaptor} or {@link ArgumentMatcher} to find out other ways of matching / asserting arguments passed.
     * <p>
     * Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b>.
     * Let's say you've stubbed <code>foo.bar()</code>.
     * If your code cares what <code>foo.bar()</code> returns then something else breaks(often before even <code>verify()</code> gets executed).
     * If your code doesn't care what <code>foo.bar()</code> returns then it should not be stubbed.
     *
     * <p>
     * See examples in javadoc for {@link Mockito} class
     *
     * @param mock to be verified
     * @return mock object itself
     */
    @CheckReturnValue
    public static <T> T verify(T mock) {
        return MOCKITO_CORE.verify(mock, times(1));
    }
    /**
     * Verifies certain behavior happened at least once / exact number of times / never. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, times(5)).someMethod("was called five times");
     *
     *   verify(mock, atLeast(2)).someMethod("was called at least two times");
     *
     *   //you can use flexible argument matchers, e.g:
     *   verify(mock, atLeastOnce()).someMethod(<b>anyString()</b>);
     * </code></pre>
     *
     * <b>times(1) is the default</b> and can be omitted
     * <p>
     * Arguments passed are compared using <code>equals()</code> method.
     * Read about {@link ArgumentCaptor} or {@link ArgumentMatcher} to find out other ways of matching / asserting arguments passed.
     * <p>
     *
     * @param mock to be verified
     * @param mode times(x), atLeastOnce() or never()
     *
     * @return mock object itself
     */
    @CheckReturnValue
    public static <T> T verify(T mock, VerificationMode mode) {
        return MOCKITO_CORE.verify(mock, mode);
    }
    /**
     * Allows verifying exact number of invocations. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, times(2)).someMethod("some arg");
     * </code></pre>
     *
     * See examples in javadoc for {@link Mockito} class
     *
     * @param wantedNumberOfInvocations wanted number of invocations
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode times(int wantedNumberOfInvocations) {
        return VerificationModeFactory.times(wantedNumberOfInvocations);
    }
    /**
     * Alias to <code>times(0)</code>, see {@link Mockito#times(int)}
     * <p>
     * Verifies that interaction did not happen. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, never()).someMethod();
     * </code></pre>
     *
     * <p>
     * If you want to verify there were NO interactions with the mock
     * check out {@link Mockito#verifyZeroInteractions(Object...)}
     * or {@link Mockito#verifyNoMoreInteractions(Object...)}
     * <p>
     * See examples in javadoc for {@link Mockito} class
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode never() {
        return times(0);
    }
    /**
     * Allows at-least-once verification. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, atLeastOnce()).someMethod("some arg");
     * </code></pre>
     * Alias to <code>atLeast(1)</code>.
     * <p>
     * See examples in javadoc for {@link Mockito} class
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode atLeastOnce() {
        return VerificationModeFactory.atLeastOnce();
    }
    /**
     * Allows at-least-x verification. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, atLeast(3)).someMethod("some arg");
     * </code></pre>
     *
     * See examples in javadoc for {@link Mockito} class
     *
     * @param minNumberOfInvocations minimum number of invocations
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode atLeast(int minNumberOfInvocations) {
        return VerificationModeFactory.atLeast(minNumberOfInvocations);
    }
    /**
     * Allows at-most-once verification. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, atMostOnce()).someMethod("some arg");
     * </code></pre>
     * Alias to <code>atMost(1)</code>.
     * <p>
     * See examples in javadoc for {@link Mockito} class
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode atMostOnce() {
        return VerificationModeFactory.atMostOnce();
    }
    /**
     * Allows at-most-x verification. E.g:
     * <pre class="code"><code class="java">
     *   verify(mock, atMost(3)).someMethod("some arg");
     * </code></pre>
     *
     * See examples in javadoc for {@link Mockito} class
     *
     * @param maxNumberOfInvocations max number of invocations
     *
     * @return verification mode
     */
    @CheckReturnValue
    public static VerificationMode atMost(int maxNumberOfInvocations) {
        return VerificationModeFactory.atMost(maxNumberOfInvocations);
    }

    验证失败对应的异常:

    异常抛出

    when() ...thenThrow(); 当满足条件时候,抛出异常

    doThrow()...when(); 满足when中条件时候,抛出异常

    当when条件中函数返回值为void时候,不可用thenThrow(),用doThrow()

    @Test
    void mockitoMethodException() {
        ArrayList mockList = mock(ArrayList.class);
        mockList.add(1);
        when(mockList.add(2)).thenThrow(new Exception("异常抛出!"));
        doThrow(new Exception("异常抛出!")).when(mockList).clear();
    }

    返回回调接口生成期望值

    when(methodCall).thenAnswer(answer));

    doAnswer(answer).when(methodCall).[method];

    调用真实的方法

    doCallRealMethod().when(mock).[method];

  3. AssertJ

    AssertJ: JAVA 流式断言器,常见的断言器一条断言语句只能对实际值断言一个校验点,而流式断言器,支持一条断言语句对实际值同时断言多个校验点。是用来验证输出和期望是否一致的一个工具。

    手册:assertj-core 3.20.2 javadoc (org.assertj)

    常用方法:

    1. as(): 添加错误提示信息

    assertThat("abc").as("校验abc").isEqualTo("abcd");
    1. isEqualsTo():相等

    2. contains():包含

    assertThat("abc").as("校验abc").isEqualTo("abc").contains("d");
    1. isNull() / isNotNull():为空判断

    Object object = null;
    assertThat(object).isNotNull();
    assertThat(object).isNull();
    1. isIn() / isNotIn():范围判断

    List list = new ArrayList();
    assertThat(list).isIn(new ArrayList(), new HashMap());
    assertThat(list).isNotIn(new ArrayList(), new HashMap());
    1. hasSize():大小校验

    List list = new ArrayList();
    assertThat(list).hasSize(1);
    1. startsWith() / endsWith()等等...可参考API

集成测试

Spring Boot项目单元测试及集成测试的应用

  1. 搭建测试环境

    Junit:Java应用程序单元测试标准类库

    Spring Test & Spring Boot Test:Spring Boot 应用程序功能集成化测试支持

    AssertJ:一个轻量级断言类库

    Hamcrest:一个对象匹配器类库,用Junit自带的即可

    Mockito: 一个java Mock测试框架

    JSONassert:一个用于JSON的断言库

    JsonPath: 一个Json操作类库

    手册

    Junit:JUnit API

    AssertJ:assertj-core 3.20.2 javadoc (org.assertj)

    Mockito:mockito-core 3.11.2 javadoc (org.mockito)

    Spring Boot Test:Spring Boot Reference Documentation

  2. 集成测试demo

    2.1 Endpoint层

    @SpringBootTest(classes = ScheduleSetup.class)
    @AutoConfigureMockMvc
    class ScheduleEndpointTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        private ScheduleService scheduleService;
    
        @BeforeEach
        void initScheduleService() {
            scheduleService = mock(ScheduleServiceImpl.class);
        }
    
        @Test
        void add_schedule() {
            try {
                System.out.println("scheduleService>>>" + scheduleService);
                //构造请求数据
                Map<String, Integer> startPolicyParams = new HashMap<>();
                ScheduleDTO scheduleDTO = ScheduleDTO.builder().name("单元测试-1").owner("lijialin").severity(Severity.HIGH)
                        .description("hah").startPolicyType(StartPolicyType.ONCE).startPolicyParams(null)
                        .startTime(System.currentTimeMillis()).paramData(null).createBy("lijialin")
                        .build();
                //模拟post请求
                mockMvc.perform(MockMvcRequestBuilders.post("/v1/soar-common/schedules")
                        .content(JsonUtil.toJson(scheduleDTO))
                        .contentType(MediaType.APPLICATION_JSON))
                /*.andExpect(MockMvcResultMatchers.status().isOk())*/;
                assertThat(scheduleService.existsByName("单元测试-1"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    2.2 Application-Service层

    class ScheduleApplicationServiceTest {
    
        private ScheduleApplicationService applicationService;
    
        private ScheduleService scheduleService;
    
        @BeforeEach
        void init() {
            applicationService = new ScheduleApplicationService(mock(ScheduleServiceImpl.class), mock(ScheduleRecordServiceImpl.class));
            scheduleService = mock(ScheduleServiceImpl.class);
        }
    
        @Test
        void edit() {
            Map<String, Integer> paramsMap = new HashMap<>();
            paramsMap.put("week", 6);
            paramsMap.put("hour", 8);
            paramsMap.put("minute", 12);
            paramsMap.put("interval", 1);
            ScheduleDTO scheduleDTO = ScheduleDTO.builder().name("新增调度1")
                    .createBy("lijialin")
                    .severity(Severity.HIGH)
                    .startTime(1646387494000L)
                    .startPolicyType(StartPolicyType.WEEKLY)
                    .endPolicyType(EndPolicyType.END_TIME)
                    .endPolicyValue(1646964300000L)
                    .startPolicyParams(paramsMap)
                    .build();
            applicationService.save(scheduleDTO);
            assertThat(scheduleService.existsByName("新增调度1"));
            ScheduleEditDTO scheduleEditDTO = ScheduleEditDTO.builder()
                    .id("37f62f73-65fc-4c00-89ff-eff295f784bf")
                    .name("编辑调度1")
                    .createBy("lijialin")
                    .severity(Severity.HIGH)
                    .startTime(1646387494000L)
                    .startPolicyType(StartPolicyType.WEEKLY)
                    .endPolicyType(EndPolicyType.END_TIME)
                    .endPolicyValue(1646784300000L)
                    .startPolicyParams(paramsMap)
                    .build();
            applicationService.edit(scheduleEditDTO);
            assertThat(scheduleService.existsByName("编辑调度1"));
        }
    }

    2.3 Domain-Service层

    @Slf4j
    class ScheduleServiceImplTest {
    
        private ScheduleService scheduleService;
    
        private Scheduler scheduler;
    
        @BeforeEach
        void init() {
            scheduler = mock(Scheduler.class);
            scheduleService = new ScheduleServiceImpl(scheduler);
        }
    
        @Test
        void addSchedule() {
            Map<String, Object> cornParams = new HashMap<>();
            cornParams.put("type", "ONCE");
            String cornParamsStr = JsonUtil.toJson(cornParams);
            ScheduleObject scheduleObject = ScheduleObject.builder().uuid("72bc5a2d-e5ee-4e83-9866-32b0df54bdb2")
                    .name("单元测试-6")
                    .creator("lijialin")
                    .owner("lijialin")
                    .type("ONCE")
                    .severity(3)
                    .description("desc...")
                    .startTime(System.currentTimeMillis())
                    .cornParams(cornParamsStr)
                    .build();
            scheduleService.addSchedule(scheduleObject);
            assertThat(scheduleService.existsByName("单元测试-6"));
        }
    
  • 25
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 Boot环境,编写单元测试集成测试是非常重要的。单元测试是针对代码的最小单元进行测试,它可以帮助开发人员验证每个单独的组件是否按预期工作。而集成测试则是测试多个组件之间的交互和集成情况,以确保它们能够正常协同工作。 在编写单元测试时,你可以使用Spring Boot提供的测试框架和注解。通过使用这些工具,你可以模拟出各种场景,包括注入依赖、模拟外部服务和数据访问等。你可以使用@SpringBootTest注解来创建Spring Boot应用测试环境,并通过@AutoConfigureMockMvc注解来模拟HTTP请求和响应。 而在集成测试,你可以通过使用Spring Boot的集成测试注解来测试整个应用程序的行为。你可以使用@SpringBootTest注解创建一个完整的应用程序上下文,并使用@AutoConfigureMockMvc注解来模拟HTTP请求和响应。此外,你还可以使用@ActiveProfiles注解来激活指定的配置文件。 总结来说,单元测试集成测试是Spring Boot应用程序开发的重要环节。通过编写和运行这些测试,你可以确保你的代码在不同的场景下能够正常工作,并提供高质量的软件。参考资料和提供了详细的指导和示例,可以帮助你更好地理解和应用Spring Boot单元测试集成测试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring Boot 的单元测试集成测试](https://blog.csdn.net/Developlee/article/details/101444784)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值