import { Injectable, Inject, isInjectable, getInjectMetadata, createInstance, registerInjectable } from '../../src/Core/DI'; import { ServiceContainer } from '../../src/Core/ServiceContainer'; import type { IService } from '../../src/Core/ServiceContainer'; // 测试服务类 @Injectable() class SimpleService implements IService { public value: string = 'simple'; dispose() { // 清理资源 } } @Injectable() class DependentService implements IService { constructor( @Inject(SimpleService) public simpleService: SimpleService ) {} dispose() { // 清理资源 } } @Injectable() class MultiDependencyService implements IService { constructor( @Inject(SimpleService) public service1: SimpleService, @Inject(DependentService) public service2: DependentService ) {} dispose() { // 清理资源 } } // 非Injectable类(用于测试错误情况) class NonInjectableService implements IService { dispose() {} } describe('DI - 依赖注入装饰器测试', () => { let container: ServiceContainer; beforeEach(() => { container = new ServiceContainer(); }); describe('@Injectable 装饰器', () => { test('应该正确标记类为可注入', () => { expect(isInjectable(SimpleService as any)).toBe(true); expect(isInjectable(DependentService as any)).toBe(true); }); test('未标记的类不应该是可注入的', () => { expect(isInjectable(NonInjectableService as any)).toBe(false); }); }); describe('@Inject 装饰器', () => { test('应该记录参数注入元数据', () => { const metadata = getInjectMetadata(DependentService as any); expect(metadata.size).toBe(1); expect(metadata.get(0)).toBe(SimpleService); }); test('应该记录多个参数的注入元数据', () => { const metadata = getInjectMetadata(MultiDependencyService as any); expect(metadata.size).toBe(2); expect(metadata.get(0)).toBe(SimpleService); expect(metadata.get(1)).toBe(DependentService); }); }); describe('createInstance', () => { test('应该创建无依赖的实例', () => { container.registerSingleton(SimpleService); const instance = createInstance(SimpleService, container); expect(instance).toBeInstanceOf(SimpleService); expect(instance.value).toBe('simple'); }); test('应该创建有依赖的实例', () => { container.registerSingleton(SimpleService); container.registerSingleton(DependentService, () => createInstance(DependentService, container) ); const instance = createInstance(DependentService, container); expect(instance).toBeInstanceOf(DependentService); expect(instance.simpleService).toBeInstanceOf(SimpleService); }); test('应该创建有多个依赖的实例', () => { container.registerSingleton(SimpleService); container.registerSingleton(DependentService, () => createInstance(DependentService, container) ); container.registerSingleton(MultiDependencyService, () => createInstance(MultiDependencyService, container) ); const instance = createInstance(MultiDependencyService, container); expect(instance).toBeInstanceOf(MultiDependencyService); expect(instance.service1).toBeInstanceOf(SimpleService); expect(instance.service2).toBeInstanceOf(DependentService); }); test('依赖应该正确解析为单例', () => { container.registerSingleton(SimpleService); container.registerSingleton(DependentService, () => createInstance(DependentService, container) ); const simple1 = container.resolve(SimpleService); const dependent = createInstance(DependentService, container); expect(dependent.simpleService).toBe(simple1); }); }); describe('registerInjectable', () => { test('应该注册可注入的服务', () => { registerInjectable(container, SimpleService); expect(container.isRegistered(SimpleService)).toBe(true); }); test('应该自动解析依赖', () => { registerInjectable(container, SimpleService); registerInjectable(container, DependentService); const instance = container.resolve(DependentService); expect(instance).toBeInstanceOf(DependentService); expect(instance.simpleService).toBeInstanceOf(SimpleService); }); test('应该正确处理多层依赖', () => { registerInjectable(container, SimpleService); registerInjectable(container, DependentService); registerInjectable(container, MultiDependencyService); const instance = container.resolve(MultiDependencyService); expect(instance).toBeInstanceOf(MultiDependencyService); expect(instance.service1).toBeInstanceOf(SimpleService); expect(instance.service2).toBeInstanceOf(DependentService); expect(instance.service2.simpleService).toBeInstanceOf(SimpleService); }); test('依赖应该是单例的', () => { registerInjectable(container, SimpleService); registerInjectable(container, DependentService); const instance1 = container.resolve(DependentService); const instance2 = container.resolve(DependentService); const simple = container.resolve(SimpleService); expect(instance1).toBe(instance2); expect(instance1.simpleService).toBe(simple); }); test('注册瞬时服务应该每次创建新实例', () => { registerInjectable(container, SimpleService); registerInjectable(container, DependentService, false); // 瞬时 const instance1 = container.resolve(DependentService); const instance2 = container.resolve(DependentService); expect(instance1).not.toBe(instance2); expect(instance1.simpleService).toBe(instance2.simpleService); // 依赖仍然是单例 }); test('注册非Injectable类应该抛出错误', () => { expect(() => { registerInjectable(container, NonInjectableService as any); }).toThrow(/not marked as @Injectable/); }); }); describe('集成测试', () => { test('完整的DI流程应该正常工作', () => { // 1. 注册所有服务 registerInjectable(container, SimpleService); registerInjectable(container, DependentService); registerInjectable(container, MultiDependencyService); // 2. 解析服务 const multi = container.resolve(MultiDependencyService); // 3. 验证依赖树 expect(multi).toBeInstanceOf(MultiDependencyService); expect(multi.service1).toBeInstanceOf(SimpleService); expect(multi.service2).toBeInstanceOf(DependentService); expect(multi.service2.simpleService).toBe(multi.service1); // 同一个实例 // 4. 验证服务功能 expect(multi.service1.value).toBe('simple'); }); }); });