Back to Repositories

Testing MongoDB Repository Operations in spring-boot-demo

This test suite demonstrates comprehensive testing of MongoDB operations in a Spring Boot application, focusing on Article repository functionality. The tests cover basic CRUD operations, pagination, and specialized MongoDB queries using both ArticleRepository and MongoTemplate.

Test Coverage Overview

The test suite provides extensive coverage of MongoDB operations:
  • CRUD operations (save, update, delete) for single and bulk Article entities
  • Pagination and sorting functionality
  • Custom queries including title search
  • Atomic operations for updating counters (thumbUp, visits)

Implementation Analysis

The testing approach utilizes both Spring Data MongoDB repository methods and MongoTemplate operations. The suite demonstrates two implementation patterns for updates: standard repository save operations and more efficient MongoDB atomic updates using MongoTemplate.

Key patterns include using @Autowired for dependency injection, JUnit 4 test annotations, and Hutool utility methods for test data generation.

Technical Details

Testing tools and configuration:
  • JUnit 4 testing framework
  • Spring Boot Test infrastructure
  • Hutool utilities for random data generation
  • Snowflake ID generation
  • MongoTemplate for low-level MongoDB operations
  • Lombok @Slf4j for logging

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Isolated test methods with clear single responsibilities
  • Comprehensive logging of test operations and results
  • Multiple implementation approaches compared (repository vs template)
  • Proper test method naming and organization
  • Effective use of utility classes for test data generation

xkcoding/spring-boot-demo

demo-mongodb/src/test/java/com/xkcoding/mongodb/repository/ArticleRepositoryTest.java

            
package com.xkcoding.mongodb.repository;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.xkcoding.mongodb.SpringBootDemoMongodbApplicationTests;
import com.xkcoding.mongodb.model.Article;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 测试操作 MongoDb
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2018-12-28 16:35
 */
@Slf4j
public class ArticleRepositoryTest extends SpringBootDemoMongodbApplicationTests {
    @Autowired
    private ArticleRepository articleRepo;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private Snowflake snowflake;

    /**
     * 测试新增
     */
    @Test
    public void testSave() {
        Article article = new Article(1L, RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L);
        articleRepo.save(article);
        log.info("【article】= {}", JSONUtil.toJsonStr(article));
    }

    /**
     * 测试新增列表
     */
    @Test
    public void testSaveList() {
        List<Article> articles = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            articles.add(new Article(snowflake.nextId(), RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L));
        }
        articleRepo.saveAll(articles);

        log.info("【articles】= {}", JSONUtil.toJsonStr(articles.stream().map(Article::getId).collect(Collectors.toList())));
    }

    /**
     * 测试更新
     */
    @Test
    public void testUpdate() {
        articleRepo.findById(1L).ifPresent(article -> {
            article.setTitle(article.getTitle() + "更新之后的标题");
            article.setUpdateTime(DateUtil.date());
            articleRepo.save(article);
            log.info("【article】= {}", JSONUtil.toJsonStr(article));
        });
    }

    /**
     * 测试删除
     */
    @Test
    public void testDelete() {
        // 根据主键删除
        articleRepo.deleteById(1L);

        // 全部删除
        articleRepo.deleteAll();
    }

    /**
     * 测试点赞数、访客数,使用save方式更新点赞、访客
     */
    @Test
    public void testThumbUp() {
        articleRepo.findById(1L).ifPresent(article -> {
            article.setThumbUp(article.getThumbUp() + 1);
            article.setVisits(article.getVisits() + 1);
            articleRepo.save(article);
            log.info("【标题】= {}【点赞数】= {}【访客数】= {}", article.getTitle(), article.getThumbUp(), article.getVisits());
        });
    }

    /**
     * 测试点赞数、访客数,使用更优雅/高效的方式更新点赞、访客
     */
    @Test
    public void testThumbUp2() {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(1L));
        Update update = new Update();
        update.inc("thumbUp", 1L);
        update.inc("visits", 1L);
        mongoTemplate.updateFirst(query, update, "article");

        articleRepo.findById(1L).ifPresent(article -> log.info("【标题】= {}【点赞数】= {}【访客数】= {}", article.getTitle(), article.getThumbUp(), article.getVisits()));
    }

    /**
     * 测试分页排序查询
     */
    @Test
    public void testQuery() {
        Sort sort = Sort.by("thumbUp", "updateTime").descending();
        PageRequest pageRequest = PageRequest.of(0, 5, sort);
        Page<Article> all = articleRepo.findAll(pageRequest);
        log.info("【总页数】= {}", all.getTotalPages());
        log.info("【总条数】= {}", all.getTotalElements());
        log.info("【当前页数据】= {}", JSONUtil.toJsonStr(all.getContent().stream().map(article -> "文章标题:" + article.getTitle() + "点赞数:" + article.getThumbUp() + "更新时间:" + article.getUpdateTime()).collect(Collectors.toList())));
    }

    /**
     * 测试根据标题模糊查询
     */
    @Test
    public void testFindByTitleLike() {
        List<Article> articles = articleRepo.findByTitleLike("更新");
        log.info("【articles】= {}", JSONUtil.toJsonStr(articles));
    }

}