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

NestJS测试中Mock带@InjectRedisClient的Redis客户端问题

Fixing Redis Mocking & Handling Dependencies in NestJS EmailSubscriptionService Tests

Let's break down how to resolve your Redis dependency issue and properly mock the other services you mentioned.

First: Resolve the REDIS_CLIENT_PROVIDER_0 Dependency Error

The root of your problem is that Nest can't find the mocked version of the Redis client injected with @InjectRedisClient('0'). The key here is to use the exact provider token that the decorator uses. Most Redis modules for Nest (like @nestjs-modules/ioredis) generate this token via a helper function called getRedisClientToken().

Here's how to correctly mock it:

import { Test } from '@nestjs/testing';
import { EmailSubscriptionService } from './email-service';
import { getRedisClientToken } from '@nestjs-modules/ioredis'; // Adjust import based on your Redis package

describe('EmailSubscriptionService', () => {
  let service: EmailSubscriptionService;
  let mockRedisClient: jest.Mocked<any>;

  beforeEach(async () => {
    // Create a mock Redis client with the methods your service uses
    mockRedisClient = {
      get: jest.fn().mockResolvedValue(null),
      set: jest.fn().mockResolvedValue('OK'),
      del: jest.fn().mockResolvedValue(1),
      // Add any other Redis commands your service calls (e.g., hgetall, expire)
    };

    const moduleRef = await Test.createTestingModule({
      providers: [
        EmailSubscriptionService,
        // Mock the Redis client using the correct token
        {
          provide: getRedisClientToken('0'), // Matches the '0' in @InjectRedisClient('0')
          useValue: mockRedisClient,
        },
        // Add mocks for your other dependencies here (ConfigService, etc.)
      ],
    }).compile();

    service = moduleRef.get<EmailSubscriptionService>(EmailSubscriptionService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  // Example test using the mocked Redis client
  it('should store a subscription in Redis', async () => {
    await service.subscribe('user@example.com');
    
    expect(mockRedisClient.set).toHaveBeenCalledWith(
      'subscription:user@example.com', 
      expect.any(String), // Assuming you stringify the subscription data
      expect.any(Object) // Optional: If you set TTL or other options
    );
  });
});

If you don't have access to getRedisClientToken(), you can directly use the token string from your error (REDIS_CLIENT_PROVIDER_0) as the provide value—though using the helper is more maintainable.


Handling Other Dependencies

Now let's cover how to mock the remaining services you mentioned:

1. ConfigService

Mock it by providing a useValue with a mocked get() method that returns the config values your service needs:

{
  provide: ConfigService,
  useValue: {
    get: jest.fn((key: string) => {
      switch (key) {
        case 'EMAIL_FROM_ADDRESS': return 'no-reply@your-app.com';
        case 'REDIS_TTL': return 86400;
        // Add all config keys your service uses
      }
    }),
  },
}

2. HttpService

Mock the HTTP client methods your service calls (e.g., post, get) to return predefined responses:

{
  provide: HttpService,
  useValue: {
    post: jest.fn().mockResolvedValue({ 
      data: { message: 'Email sent successfully' } 
    }),
    // Mock other methods like get/put/delete if needed
  },
}

3. ManageSavedSearchService

If this is a custom service in your app, mock its public methods that EmailSubscriptionService relies on:

{
  provide: ManageSavedSearchService,
  useValue: {
    getUserSavedSearches: jest.fn().mockResolvedValue([
      { id: 1, query: 'latest news' }
    ]),
    // Add other methods your service calls
  },
}

Troubleshooting Tips

  • Double-check all dependencies: Ensure every dependency of EmailSubscriptionService is included in the testing module (either as a mock or real instance).
  • Verify mock methods: Make sure your mocks implement all the methods the service uses—missing methods will throw errors.
  • Use spies if needed: If you need to track calls to a real service (unlikely in unit tests), use jest.spyOn() instead of a full mock.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:47:39