You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为List<Overview>编写JUnit单元测试?请求技术协助

Hey there, I totally get how frustrating it is to get stuck writing unit tests for database-related code—especially when you're still wrapping your head around how unit testing works with MongoDB. Let's break this down step by step to get you unblocked!

First, let's clarify: unit testing for this method means isolating your code from the actual MongoDB database. We don't want to hit a real database in unit tests—instead, we'll mock the Mongo-related dependencies (like MongoTemplate or Spring Data MongoRepository) to control their behavior.


Step 1: Define Your Test Scenarios

We need to cover the main paths your method can take:

  • Happy path: When a valid status is provided, the method returns the correct list of Overview objects.
  • Error path: When the underlying Mongo operation fails, the method correctly throws your CustomMongoException.

Step 2: Set Up Test Dependencies

Assuming you're using JUnit 5 and Mockito (the most common combo for Java unit tests), add these dependencies to your build file (Maven example):

<!-- JUnit 5 -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
<!-- Mockito for mocking dependencies -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>

Step 3: Write the Test Code

Let's assume your service/class looks like this (adjust if your implementation differs):

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.stereotype.Service;

import java.util.List;

@Service
public class OverviewService {
    private final MongoTemplate mongoTemplate;

    public OverviewService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public List<Overview> findOverviewByStatus(String status) throws CustomMongoException {
        try {
            Query query = Query.query(Criteria.where("status").is(status));
            return mongoTemplate.find(query, Overview.class);
        } catch (MongoException e) {
            throw new CustomMongoException("Failed to fetch overviews by status", e);
        }
    }
}

// Your custom exception class
class CustomMongoException extends Exception {
    public CustomMongoException(String message, Throwable cause) {
        super(message, cause);
    }
}

// Your Overview model
class Overview {
    private String id;
    private String status;
    private String name;

    // Constructor, getters, setters
    public Overview(String id, String status, String name) {
        this.id = id;
        this.status = status;
        this.name = name;
    }

    public String getId() { return id; }
    public String getStatus() { return status; }
    public String getName() { return name; }
}

Now here's the unit test class:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class OverviewServiceTest {

    // Mock the MongoTemplate so we don't hit a real database
    @Mock
    private MongoTemplate mongoTemplate;

    // Inject the mocked MongoTemplate into our service under test
    @InjectMocks
    private OverviewService overviewService;

    @Test
    void findOverviewByStatus_ValidStatus_ReturnsMatchingOverviews() throws CustomMongoException {
        // 1. Prepare test data
        String testStatus = "ACTIVE";
        Overview testOverview1 = new Overview("id1", testStatus, "Q3 Sales Overview");
        Overview testOverview2 = new Overview("id2", testStatus, "Q4 Marketing Overview");
        List<Overview> expectedOverviews = List.of(testOverview1, testOverview2);

        // 2. Tell Mockito what to do when mongoTemplate.find() is called
        when(mongoTemplate.find(any(Query.class), eq(Overview.class)))
                .thenReturn(expectedOverviews);

        // 3. Run the method we're testing
        List<Overview> actualOverviews = overviewService.findOverviewByStatus(testStatus);

        // 4. Verify the results are correct
        assertEquals(expectedOverviews.size(), actualOverviews.size());
        assertEquals(expectedOverviews.get(0).getId(), actualOverviews.get(0).getId());
        // Make sure mongoTemplate.find() was called exactly once
        verify(mongoTemplate, times(1)).find(any(Query.class), eq(Overview.class));
    }

    @Test
    void findOverviewByStatus_MongoFails_ThrowsCustomMongoException() {
        // 1. Prepare test data
        String testStatus = "INVALID";
        MongoException mockMongoError = new MongoException("Connection timed out");

        // 2. Tell Mockito to throw an exception when mongoTemplate.find() is called
        when(mongoTemplate.find(any(Query.class), eq(Overview.class)))
                .thenThrow(mockMongoError);

        // 3. Verify our method throws the custom exception
        CustomMongoException thrownException = assertThrows(CustomMongoException.class,
                () -> overviewService.findOverviewByStatus(testStatus));

        // Check exception details are correct
        assertEquals("Failed to fetch overviews by status", thrownException.getMessage());
        assertEquals(mockMongoError, thrownException.getCause());
        // Ensure mongoTemplate.find() was called once
        verify(mongoTemplate, times(1)).find(any(Query.class), eq(Overview.class));
    }
}

Key Things to Keep in Mind

  • Mock external dependencies: The goal is to test your code, not MongoDB. Mocking MongoTemplate or MongoRepository lets you control exactly what data is returned (or what error is thrown) without needing a real database.
  • Cover edge cases: Add tests for scenarios like an empty status string (if your method allows it), or when Mongo returns an empty list.
  • If you use Spring Data Repositories: If your code uses a MongoRepository interface instead of MongoTemplate, the approach is almost identical—just mock the repository interface instead of MongoTemplate.

内容的提问来源于stack exchange,提问作者nico43624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:22:27