| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- package tool
- import (
- "context"
- "fmt"
- "testing"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/mongo/readpref"
- )
- // 配置测试用的 MongoDB 连接信息
- var cfg = Config{
- Uri: "mongodb://localhost:27017", // 请根据实际情况修改
- Database: "test",
- Username: "test",
- Password: "123456",
- }
- func TestInitMongo(t *testing.T) {
- // 调用 InitMongo 方法
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("InitMongo failed: %v", err)
- }
- defer func() {
- // 测试结束后断开连接
- err := repo.DB.Client().Disconnect(context.TODO())
- if err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- // 验证连接是否成功
- err = repo.DB.Client().Ping(context.TODO(), readpref.Primary())
- if err != nil {
- t.Errorf("Failed to ping MongoDB: %v", err)
- }
- // 验证数据库实例是否正确
- if repo.DB.Name() != cfg.Database {
- t.Errorf("Expected database name %s, but got %s", cfg.Database, repo.DB.Name())
- }
- }
- // TestInsertOne 测试 InsertOne 方法
- func TestInsertOne(t *testing.T) {
- // 初始化 MongoDB 连接,使用全局的 cfg
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- // 测试结束后断开连接
- err := repo.DB.Client().Disconnect(context.TODO())
- if err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- // 验证连接是否成功
- err = repo.DB.Client().Ping(context.TODO(), readpref.Primary())
- if err != nil {
- t.Fatalf("Failed to ping MongoDB: %v", err)
- }
- // 准备测试数据
- collectionName := "testCollection"
- testDocument := bson.M{
- "name": "Test User",
- "age": 25,
- "email": "test@example.com",
- }
- // 调用 InsertOne 方法
- result, err := repo.InsertOne(context.TODO(), collectionName, testDocument)
- if err != nil {
- t.Fatalf("InsertOne failed: %v", err)
- }
- // 验证插入结果
- if result.InsertedID == nil {
- t.Errorf("InsertedID is nil, insert may have failed")
- }
- // 验证文档是否实际插入到数据库
- var insertedDoc bson.M
- err = repo.DB.Collection(collectionName).FindOne(context.TODO(), bson.M{"_id": result.InsertedID}).Decode(&insertedDoc)
- if err != nil {
- t.Errorf("Failed to find inserted document: %v", err)
- }
- // 打印查询出来的插入数据
- fmt.Printf("查询到的插入数据: %+v\n", insertedDoc)
- // 清理测试数据
- _, err = repo.DB.Collection(collectionName).DeleteOne(context.TODO(), bson.M{"_id": result.InsertedID})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- }
- func TestUpsert(t *testing.T) {
- // 使用全局 cfg 初始化 MongoDB 连接
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- // 测试结束后断开连接
- err = repo.DB.Client().Disconnect(context.TODO())
- if err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- // 验证连接是否成功
- err = repo.DB.Client().Ping(context.TODO(), readpref.Primary())
- if err != nil {
- t.Fatalf("Failed to ping MongoDB: %v", err)
- }
- collectionName := "testUpsertCollection"
- // 测试文档不存在时的 Upsert
- t.Run("Upsert when document does not exist", func(t *testing.T) {
- filter := bson.M{"name": "newUser"}
- update := bson.M{"$set": bson.M{"age": 25}}
- result, err := repo.Upsert(context.TODO(), collectionName, filter, update)
- if err != nil {
- t.Fatalf("Upsert failed: %v", err)
- }
- if result.MatchedCount != 0 {
- t.Errorf("Expected matched count 0, got %d", result.MatchedCount)
- }
- if result.ModifiedCount != 0 {
- t.Errorf("Expected modified count 0, got %d", result.ModifiedCount)
- }
- if result.UpsertedID == nil {
- t.Errorf("Expected non-nil upserted ID, got nil")
- }
- // 查询插入的文档
- var insertedDoc bson.M
- err = repo.DB.Collection(collectionName).FindOne(context.TODO(), bson.M{"_id": result.UpsertedID}).Decode(&insertedDoc)
- if err != nil {
- t.Errorf("Failed to find inserted document: %v", err)
- }
- // 打印插入的文档
- fmt.Printf("插入的文档: %+v\n", insertedDoc)
- // 清理测试数据
- _, err = repo.DB.Collection(collectionName).DeleteOne(context.TODO(), bson.M{"_id": result.UpsertedID})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- })
- // 测试文档存在时的 Upsert
- t.Run("Upsert when document exists", func(t *testing.T) {
- // 先插入一个文档
- insertResult, err := repo.InsertOne(context.TODO(), collectionName, bson.M{"name": "existingUser", "age": 20})
- if err != nil {
- t.Fatalf("Failed to insert test document: %v", err)
- }
- filter := bson.M{"name": "existingUser"}
- update := bson.M{"$set": bson.M{"age": 30}}
- result, err := repo.Upsert(context.TODO(), collectionName, filter, update)
- if err != nil {
- t.Fatalf("Upsert failed: %v", err)
- }
- if result.MatchedCount != 1 {
- t.Errorf("Expected matched count 1, got %d", result.MatchedCount)
- }
- if result.ModifiedCount != 1 {
- t.Errorf("Expected modified count 1, got %d", result.ModifiedCount)
- }
- if result.UpsertedID != nil {
- t.Errorf("Expected nil upserted ID, got %v", result.UpsertedID)
- }
- // 查询更新后的文档
- var updatedDoc bson.M
- err = repo.DB.Collection(collectionName).FindOne(context.TODO(), bson.M{"_id": insertResult.InsertedID}).Decode(&updatedDoc)
- if err != nil {
- t.Errorf("Failed to find updated document: %v", err)
- }
- // 打印更新后的文档
- fmt.Printf("更新后的文档: %+v\n", updatedDoc)
- // 清理测试数据
- _, err = repo.DB.Collection(collectionName).DeleteOne(context.TODO(), bson.M{"_id": insertResult.InsertedID})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- })
- }
- // TestNestedQuery 测试 NestedQuery 方法
- func TestNestedQuery(t *testing.T) {
- // 使用全局 cfg 初始化 MongoDB 连接
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- // 测试结束后断开连接
- err = repo.DB.Client().Disconnect(context.TODO())
- if err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- // 验证连接是否成功
- err = repo.DB.Client().Ping(context.TODO(), readpref.Primary())
- if err != nil {
- t.Fatalf("Failed to ping MongoDB: %v", err)
- }
- collectionName := "testNestedQueryCollection"
- // 准备测试数据
- testDocuments := []interface{}{
- bson.M{
- "name": "Alice",
- "address": bson.M{
- "city": "New York",
- "zip": "10001",
- },
- },
- bson.M{
- "name": "Bob",
- "address": bson.M{
- "city": "Los Angeles",
- "zip": "90001",
- },
- },
- }
- // 插入测试数据
- _, err = repo.DB.Collection(collectionName).InsertMany(context.TODO(), testDocuments)
- if err != nil {
- t.Fatalf("Failed to insert test documents: %v", err)
- }
- // 定义嵌套查询条件
- nestedFilter := bson.M{
- "address.city": "New York",
- }
- // 执行嵌套查询
- cursor, err := repo.NestedQuery(context.TODO(), collectionName, nestedFilter)
- if err != nil {
- t.Fatalf("NestedQuery failed: %v", err)
- }
- defer cursor.Close(context.TODO())
- // 遍历游标并验证结果
- var results []bson.M
- for cursor.Next(context.TODO()) {
- var result bson.M
- err = cursor.Decode(&result)
- if err != nil {
- t.Errorf("Failed to decode document: %v", err)
- continue
- }
- results = append(results, result)
- }
- if err = cursor.Err(); err != nil {
- t.Errorf("Cursor error: %v", err)
- }
- // 验证查询结果数量
- if len(results) != 1 {
- t.Errorf("Expected 1 result, got %d", len(results))
- }
- // 打印查询结果
- fmt.Printf("查询结果: %+v\n", results)
- // 验证查询结果内容
- if results[0]["name"] != "Alice" {
- t.Errorf("Expected name 'Alice', got %v", results[0]["name"])
- }
- // 清理测试数据
- _, err = repo.DB.Collection(collectionName).DeleteMany(context.TODO(), bson.M{})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- }
- // 测试 QueryArrayContains 方法
- func TestQueryArrayContains(t *testing.T) {
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- if err := repo.DB.Client().Disconnect(context.TODO()); err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- collectionName := "testArrayContains"
- // 准备测试数据
- testDocuments := []interface{}{
- bson.M{"name": "doc1", "tags": []string{"apple", "banana"}},
- bson.M{"name": "doc2", "tags": []string{"cherry", "date"}},
- }
- // 插入测试数据
- _, err = repo.DB.Collection(collectionName).InsertMany(context.TODO(), testDocuments)
- if err != nil {
- t.Fatalf("Failed to insert test documents: %v", err)
- }
- // 执行查询
- elements := []interface{}{"apple"}
- cursor, err := repo.QueryArrayContains(context.TODO(), collectionName, "tags", elements)
- if err != nil {
- t.Fatalf("QueryArrayContains failed: %v", err)
- }
- defer cursor.Close(context.TODO())
- // 验证结果
- var results []bson.M
- for cursor.Next(context.TODO()) {
- var result bson.M
- if err := cursor.Decode(&result); err != nil {
- t.Errorf("Failed to decode document: %v", err)
- continue
- }
- results = append(results, result)
- }
- // 打印查询结果
- fmt.Printf("查询结果: %+v\n", results)
- if len(results) != 1 || results[0]["name"] != "doc1" {
- t.Errorf("Expected 1 result, got %d", len(results))
- }
- // 清理数据
- _, err = repo.DB.Collection(collectionName).DeleteMany(context.TODO(), bson.M{})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- }
- func TestQueryArrayWithComplexFilter(t *testing.T) {
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- if err := repo.DB.Client().Disconnect(context.TODO()); err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- collectionName := "testArrayWithComplexFilter"
- // 准备测试数据
- testDocuments := []interface{}{
- bson.M{
- "name": "product1",
- "reviews": []bson.M{
- {"rating": 4, "author": "Alice"},
- {"rating": 2, "author": "Bob"},
- },
- },
- bson.M{
- "name": "product2",
- "reviews": []bson.M{
- {"rating": 1, "author": "Charlie"},
- {"rating": 3, "author": "David"},
- },
- },
- }
- // 插入测试数据
- _, err = repo.DB.Collection(collectionName).InsertMany(context.TODO(), testDocuments)
- if err != nil {
- t.Fatalf("Failed to insert test documents: %v", err)
- }
- // 定义复合筛选条件
- complexFilter := bson.M{
- "rating": bson.M{"$gte": 3},
- "author": "Alice",
- }
- // 执行查询
- cursor, err := repo.QueryArrayWithComplexFilter(context.TODO(), collectionName, "reviews", complexFilter)
- if err != nil {
- t.Fatalf("QueryArrayWithComplexFilter failed: %v", err)
- }
- defer cursor.Close(context.TODO())
- // 验证结果
- var results []bson.M
- for cursor.Next(context.TODO()) {
- var result bson.M
- if err := cursor.Decode(&result); err != nil {
- t.Errorf("Failed to decode document: %v", err)
- continue
- }
- results = append(results, result)
- }
- fmt.Printf("查询结果: %+v\n", results)
- if len(results) != 1 || results[0]["name"] != "product1" {
- t.Errorf("Expected 1 result, got %d", len(results))
- }
- // 清理数据
- _, err = repo.DB.Collection(collectionName).DeleteMany(context.TODO(), bson.M{})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- }
- func TestQueryArrayElementByIndex(t *testing.T) {
- repo, err := InitMongo(cfg)
- if err != nil {
- t.Fatalf("Failed to initialize MongoDB: %v", err)
- }
- defer func() {
- if err := repo.DB.Client().Disconnect(context.TODO()); err != nil {
- t.Errorf("Failed to disconnect from MongoDB: %v", err)
- }
- }()
- // 验证连接
- if err := repo.DB.Client().Ping(context.TODO(), readpref.Primary()); err != nil {
- t.Fatalf("Failed to ping MongoDB: %v", err)
- }
- collectionName := "testQueryArrayElementByIndex"
- // 准备测试数据
- testDocuments := []interface{}{
- bson.M{
- "name": "doc1",
- "numbers": []int{10, 20, 30},
- },
- bson.M{
- "name": "doc2",
- "numbers": []int{40},
- },
- }
- // 插入测试数据
- _, err = repo.DB.Collection(collectionName).InsertMany(context.TODO(), testDocuments)
- if err != nil {
- t.Fatalf("Failed to insert test documents: %v", err)
- }
- // 按索引位置查询元素
- index := 1
- cursor, err := repo.QueryArrayElementByIndex(context.TODO(), collectionName, "numbers", index)
- if err != nil {
- t.Fatalf("QueryArrayElementByIndex failed: %v", err)
- }
- defer cursor.Close(context.TODO())
- // 验证结果
- var results []bson.M
- for cursor.Next(context.TODO()) {
- var result bson.M
- if err := cursor.Decode(&result); err != nil {
- t.Errorf("Failed to decode document: %v", err)
- continue
- }
- results = append(results, result)
- }
- if len(results) != 1 {
- t.Errorf("Expected 1 result, got %d", len(results))
- }
- // 清理数据
- _, err = repo.DB.Collection(collectionName).DeleteMany(context.TODO(), bson.M{})
- if err != nil {
- t.Errorf("Failed to clean up test data: %v", err)
- }
- }
|