In production-grade Angular applications, API URLs and other environment-specific properties are typically configured through environment files located in the src/environments/
directory. These can be generated using the Angular CLI command:
ng generate environments
This creates the standard environment files:
-
environment.ts
(production defaults) -
environment.development.ts
(development configuration) - You could add other environments like staging...
Secure Configuration Management
For security best practices:
- Never commit sensitive URLs directly in environment files
- Use CI/CD variables (GitLab, GitHub Actions, etc.) to inject values during build
Protect repository variables by marking them as:
- Masked (hidden in logs)
- Protected (only available on protected branches)
Update the files:
environment.ts
export const environment = { production: true, API_URL: '${API_URL}' // CI/CD variable - This will be replaced during build };
environment.development.ts
export const environment = { production: false, API_URL: 'https://api.example.com/data' // Used only in development };
Use the environment variables:
data-http.service.ts
... import { environment } from '../environments/environment'; @Injectable({ providedIn: 'root' }) export class DataHttpService { http = inject(HttpClient); getData(): Observable<unknown> { return this.http.get<unknown>(environment.API_URL); } }
Unit testing with environment mocks
You could add an environment global mock in setup-jest.ts
:
... jest.mock('./src/environments/environment', () => ({ environment: { API_URL: 'https://api.example.com/data', production: false } }));
Mocking environment variables in unit tests is strongly recommended to ensure isolation, consistency, and security while testing all scenarios.
data-http.service.spec.ts
import { TestBed } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { DataHttpService } from './data-http.service'; import { environment } from '../environments/environment'; describe('DataHttpService', () => { let service: DataHttpService; let httpMock: HttpTestingController; const mockData = { id: 1, name: 'Test Data' }; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [DataHttpService] }); service = TestBed.inject(DataHttpService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { httpMock.verify(); // Verify no outstanding requests }); it('should use mock API_URL', () => { expect(environment.API_URL).toBe('https://api.example.com/data'); // Url defined in the setup-jest.ts file }); describe('.getData', () => { it('should make GET request and return data', () => { service.getData().subscribe(data => { expect(data).toEqual(mockData); }); const req = httpMock.expectOne(environment.API_URL); expect(req.request.method).toEqual('GET'); req.flush(mockData); }); }); });
Top comments (0)