In our angular app, we use environment files to load some config.
environment.ts
export const environment = {
production: false,
defaultLocale: 'en_US',
};
We then use it in one of our service:
import { environment } from '../../environments/environment';
import { TranslateService } from './translate.service';
@Injectable()
export class LocaleService {
constructor(private translateService: TranslateService){}
useDefaultLocaleAsLang(): void {
const defaultLocale = environment.defaultLocale;
this.translateService.setUsedLang(defaultLocale);
}
}
So I use the values in environment file in a service method.
In our test file, we can of course Spy on the translateService:
translateService = jasmine.createSpyObj('translateService', ['setUsedLang']);
But I don't know how to mock the environment values in my testing file (in a beforeEach
for example). Or even transform it, for testing purpose, to a Subject
so I can change it and test different behaviors.
More generally speaking, how can you mock such imports values in tests to be sure not to use real values?
In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test. Mocking makes sense in a unit testing context.
On WindowsIn the command window that opens, enter echo %VARIABLE%. Replace VARIABLE with the name of the environment variable you set earlier. For example, to check if MARI_CACHE is set, enter echo %MARI_CACHE%. If the variable is set, its value is displayed in the command window.
You can't test/mock environment.ts
. It is not part of Angular's DI system, it is a hard dependency on a file on the filesystem. Angular's compilation process is what enables swapping out the different environment.*.ts
files under the hood when you do a build.
Angular's DI system is a typical Object Oriented approach for making parts of your application more testable and configurable.
My recommendation would be to take advantage of the DI system and use something like this sparingly
import { environment } from '../../environments/environment';
Instead do the same thing Angular does for any dependencies it wants you to be abstracted away from. Make a service that provides a seam between the environment.ts
data and your application pieces.
It doesn't need to have any logic, it could simply pass through the properties of environment
directly (therefore it wouldn't need tested itself).
Then update your services/components that depend on environment.ts
and replace that dependency with the service. At test time you can mock it, sourcing the data from somewhere other than environment.ts
Something like this worked for me:
it('should ...', () => {
environment.defaultLocale = <location-to-test>; // e.g. 'en'
const result = service.method();
expect(result).toEqual(<expected-result>);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With