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

NodeJS环境下Mock ArangoJS单元测试及ArangoDB许可证查询函数问题

Got it, let's break down how to set up unit tests with mocking for your ArangoJS-powered listLicenses function in Node.js. I'll use Jest here since it's the most common testing framework with built-in mocking tools, but the core ideas apply to other tools like Sinon too.

背景

You're working with a service that uses ArangoDB to store license data, and you want to test the listLicenses function without spinning up a real database instance. The goal is to mock the ArangoJS client interactions so we can validate the function's logic in isolation.

核心思路

We need to:

  1. Mock the ArangoJS database connection and collection references
  2. Simulate the AQL query execution to return preset test data (or errors for failure cases)
  3. Verify that listLicenses calls the right ArangoJS methods and returns the expected results

具体实现

First, let's assume your service code lives in licenseService.js (I've filled out the incomplete listLicenses function for context):

// licenseService.js
const arangojs = require('arangojs');

class LicenseService {
  constructor() {
    this.db = new arangojs.Database({ url: 'http://localhost:8529' });
  }

  async useLicenseDb() {
    // Switch to your license database
    await this.db.useDatabase('licenseDb');
    // Authenticate if needed (mock this too!)
    await this.db.login('username', 'password');
  }

  async listLicenses() {
    let result = [];
    await this.useLicenseDb();
    const licenseCol = await this.db.collection('licenseCollection');
    try {
      const query = `
        FOR doc in licenseCollection 
        RETURN {
          licenseId: doc.licenseId, 
          licenseName: doc.licenseName, 
          clientName: doc.clientName, 
          useCase: doc.useCase, 
          expirationDate: doc.expirationDate, 
          callType: doc.callType
        }
      `;
      const cursor = await this.db.query(query);
      result = await cursor.all();
    } catch (err) {
      console.error('Failed to fetch licenses:', err);
      throw err;
    }
    return result;
  }
}

module.exports = LicenseService;

Now, create your test file licenseService.test.js:

// licenseService.test.js
const LicenseService = require('./licenseService');
const arangojs = require('arangojs');

// Mock the entire arangojs module to avoid real DB calls
jest.mock('arangojs', () => {
  // Mock the cursor object that returns our test data
  const mockCursor = {
    all: jest.fn().mockResolvedValue([
      { 
        licenseId: 'LIC-001', 
        licenseName: 'Enterprise Pro', 
        clientName: 'Acme Corp', 
        useCase: 'SaaS Platform', 
        expirationDate: '2025-12-31', 
        callType: 'REST' 
      },
      { 
        licenseId: 'LIC-002', 
        licenseName: 'Basic', 
        clientName: 'Small Biz Inc', 
        useCase: 'Internal Tools', 
        expirationDate: '2024-06-30', 
        callType: 'GraphQL' 
      }
    ])
  };

  // Mock the database instance with required methods
  const mockDb = {
    useDatabase: jest.fn().mockResolvedValue(true),
    login: jest.fn().mockResolvedValue(true),
    collection: jest.fn().mockResolvedValue({}),
    query: jest.fn().mockResolvedValue(mockCursor)
  };

  // Return the mock Database constructor
  return {
    Database: jest.fn().mockReturnValue(mockDb)
  };
});

describe('LicenseService.listLicenses', () => {
  let licenseService;

  // Reset mocks before each test to avoid cross-test contamination
  beforeEach(() => {
    licenseService = new LicenseService();
    jest.clearAllMocks();
  });

  it('should fetch and return the correct list of licenses', async () => {
    // Execute the function
    const licenses = await licenseService.listLicenses();

    // Verify ArangoJS methods were called correctly
    expect(arangojs.Database().useDatabase).toHaveBeenCalledWith('licenseDb');
    expect(arangojs.Database().collection).toHaveBeenCalledWith('licenseCollection');
    expect(arangojs.Database().query).toHaveBeenCalledWith(expect.stringContaining(
      'FOR doc in licenseCollection RETURN {licenseId: doc.licenseId, licenseName: doc.licenseName, clientName: doc.clientName, useCase: doc.useCase, expirationDate: doc.expirationDate, callType: doc.callType}'
    ));

    // Verify the returned data matches our mock
    expect(licenses).toEqual([
      { 
        licenseId: 'LIC-001', 
        licenseName: 'Enterprise Pro', 
        clientName: 'Acme Corp', 
        useCase: 'SaaS Platform', 
        expirationDate: '2025-12-31', 
        callType: 'REST' 
      },
      { 
        licenseId: 'LIC-002', 
        licenseName: 'Basic', 
        clientName: 'Small Biz Inc', 
        useCase: 'Internal Tools', 
        expirationDate: '2024-06-30', 
        callType: 'GraphQL' 
      }
    ]);
  });

  it('should handle query errors properly', async () => {
    // Override the mock query to throw an error
    const testError = new Error('AQL query failed: invalid syntax');
    arangojs.Database().query.mockRejectedValue(testError);

    // Spy on console.error to verify it's called
    const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();

    // Verify the function throws the error
    await expect(licenseService.listLicenses()).rejects.toThrow(testError);
    // Verify the error was logged
    expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to fetch licenses:', testError);

    // Clean up the spy
    consoleErrorSpy.mockRestore();
  });
});

关键注意事项

  • Mock Scope: Make sure your mock covers all ArangoJS methods your service uses (like login if you authenticate, useDatabase, etc.).
  • Test Coverage: Always test both success and failure paths to ensure error handling works as expected.
  • Mock Cleanup: Use jest.clearAllMocks() in beforeEach to reset mock call history between tests.
  • Flexible Mocks: If you need different test data for different cases, you can override the mock's resolved value in individual tests (like we did for the error case).

依赖安装

Don't forget to install the required testing dependencies:

npm install --save-dev jest

内容的提问来源于stack exchange,提问作者Lëmön

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:39:20