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

在Angular中使用升级后的AngularJS组件,测试时遇[$injector:unpr]错误

解决AngularJS指令在Angular组件测试中注入失败的问题

嘿,我之前在Angular和AngularJS混合开发的测试里踩过一模一样的坑!这个[$injector:unpr]错误的核心原因是:你在Angular的TestBed环境里尝试直接注入AngularJS的指令,但Angular的测试注入器和AngularJS的$injector是完全独立的两个系统,根本找不到contactBoxDirective的provider。下面是具体的解决步骤:

1. 先搭好Angular与AngularJS的测试兼容桥梁

首先得确保测试模块里引入了UpgradeModule,这是混合开发测试的核心依赖,还要初始化AngularJS的注入器:

import { UpgradeModule } from '@angular/upgrade/static';
import { TestBed } from '@angular/core/testing';
import { personInfoComponent } from './person-info.component';

describe('personInfo Component', () => {
  let upgradeModule: UpgradeModule;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [UpgradeModule],
      declarations: [personInfoComponent]
    }).compileComponents();

    // 初始化AngularJS注入器,这里要替换成你自己的AngularJS模块名
    upgradeModule = TestBed.inject(UpgradeModule);
    upgradeModule.bootstrap(document.body, ['yourAngularJSModuleName']);
  });
});

2. 别直接注入指令,通过模板渲染来测试

AngularJS指令是靠模板渲染生效的,不是像Angular服务那样注入使用的。所以你的测试应该聚焦在组件渲染后,指令是否正常渲染,而不是尝试注入contactBoxDirective:

it('should render contactBoxDirective properly', () => {
  const fixture = TestBed.createComponent(personInfoComponent);
  fixture.detectChanges();
  
  // 先检查指令对应的DOM元素是否存在(这里假设指令的标签选择器是<contact-box>)
  const contactBoxElement = fixture.nativeElement.querySelector('contact-box');
  expect(contactBoxElement).toBeTruthy();
  
  // 如果要测试指令的内部逻辑,可以通过AngularJS的$injector获取它的控制器
  const contactBoxDirectiveDefs = upgradeModule.$injector.get('contactBoxDirective');
  // 注意:get返回的是数组,因为可能有多个同名指令(不同限制符,比如E/A/C),取第一个就行
  const contactBoxCtrl = contactBoxDirectiveDefs[0].controller;
  // 这里可以对控制器的方法或属性做断言
});

3. 检查AngularJS模块的注册

一定要确认包含contactBoxDirective的AngularJS模块,已经在上面的bootstrap步骤里正确引入了,也就是yourAngularJSModuleName必须是你定义contactBoxDirective的那个模块名,不然测试时还是找不到指令。

4. 分清Angular和AngularJS的注入方式

最后再提醒一句,别搞混两者的注入逻辑:

  • Angular的服务/组件用TestBed.inject()获取
  • AngularJS的服务/指令用upgradeModule.$injector.get()获取,而且指令返回的是数组,要根据你的指令类型(元素/属性/类)取对应的项。

另外,也可以再检查下你的contactBoxDirective在AngularJS里的注册是否正确,比如是不是在对应的模块里用directive方法注册了:

// AngularJS模块中的指令注册示例
angular.module('yourAngularJSModuleName')
  .directive('contactBox', function() {
    return {
      restrict: 'E', // 假设你用的是元素指令
      template: '<div class="contact-box">...</div>',
      controller: function() {
        // 控制器逻辑
      }
    };
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:20:00