-
-
Notifications
You must be signed in to change notification settings - Fork 576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to unit test a component with TranslateService and the translate pipe? #636
Comments
If you unit test your component, then you should mock the service. And then do something like this:
or you return the key with a suffix, so you know "the service was called". Because when you unit test your component, you should rely on that external dependencies (like the translateService) are already tested and they are working. |
Can anyone suggest on my issue #627 |
@kartheininger If I do that I receive this error
because I'm using both TranslateService and pipe. To be more accurate: |
@kartheininger Also, adding both TranslatePipe to my declarations and your mock I get this:
|
Have you tried to use the real pipe and the mock i suggested together? I don`t know if thats working, because in our app we mocked both in tests. If you use the pipe too, then i would add a mock for the pipe too. I copied a small example within #635 I personally would just let the mocks return the key a bit modified e.g. with a 1 at the end. So you know the pipe/service was called. I hope i got you right and thats what you wanna test :) |
yes. Using Service mock and the real pipe I get this error: "Failed: this.translate.get(...) is undefined" My problem is that I don't wanna use mocks. I can't test that my components are ok, without to know that translations are correct. I don't wanna test TranslateService or other, but that they are applying the right translations in my component. I think that this is a use case where mocks are very bad. It should be possibile to apply real translations. Only with real translations I will be sure that everything will be ok in production. |
I updated your mock because you forgot to add "return":
but now I'm receiving:
It isn't so simple to mock this service. |
If that method in your test is missing, then you need to add it to the Stub :) In our tests we do not need more methods mocked, as the user cannot change his language without leaving the app and reloading it (user settings are done in a different system :)) |
@kartheininger Any example mock that you are using in your. I am having problem with TranslateDirective. Do I need to mock this too? It will be nice to include a unit testing example project in your examples folder. |
By the way, to save you time of mocking manually everything https://github.com/hirezio/jasmine-auto-spies Where you could do something like -
and get a simple API of -
It will also auto mock your sync methods as well (without having to specify them). |
I'm just coming up to speed on this stack and was trying to wrap some tests around an Ionic component. I ran across this same problem and solved it by looking at Essentially I had to define
This seems like a crazy amount of configuration and mocking for every component but I'm new to the Angular stack... |
how to load translate JSON file in karma? |
@pherris Nice work! Spent so much time trying to get that damn translatemodule to work. |
This is a crazy amount of extra work and becomes very cumbersome if this has to be included in every test. There must be an easier way, or not? |
@kgish You could probably create a custom object for the testingmodule and import it into each test? If you had anything extra to add to the testing module, you could always extend that object via a class or dynamically. |
Yes indeed. Based on #471, I tried extracting all of the translation-specific stuff into a separate helper module, but was unable to come up with a simple solution. Any hints or tips would be greatly appreciated. |
I've got everything I need mocked out (translate pipe and setDefaultLang) using Jest. I'll see if I can pull together a complete spec with just the translation piece in it (at the moment, it's all mixed-in with project-specific code) |
Thanks to @pherris, @Ks89 and https://stackoverflow.com/a/43833423 one possible solution that checks all supported languages is. ADVANTAGE: Uses real translation files/contents (json) to validate element contents. In case keys are change inside translation file (json) tests will fail. ATTENTION: code most probably will not compile. serves as an example what steps are to be done.
|
I have added a test example here if you still need it: https://github.com/ngx-translate/example/blob/master/src/app/app.component.spec.ts |
@ocombe would it be possible to show a test example of app.component.spec.ts in an Ionic 3 project using Karma/Jasmine combination? I get "The pipe 'translate' could not be found" errors when using your example. |
I've never used ionic, but maybe @danielsogl could help out? |
I can verify that Oliver (ocombe)'s test example code worked. Thanks Oliver!! |
Yes, this may work but it is still quite inconvenient to have to include all of this boiler-plate code in every test that depends on ngx-translate. There must be a better option possible? |
Can't @kgish more. I don't want to include all of the components into my test file |
Angular provides a module HttpClientTestingModule for mocking HttpClient. Why not follow the same pattern here and provide this as a first-party module for testability of your project? |
I was able to run tests with configuration mentioned above, but, on one of my test's, when I used the pipe I got this error "Error: Parameter "key" required" but when I switched to directive it did work?
|
agree with @kbirger import { Injectable, NgModule, Pipe, PipeTransform } from '@angular/core';
import { TranslateLoader, TranslateModule, TranslatePipe, TranslateService } from '@ngx-translate/core';
import { Observable, of } from 'rxjs';
const translations: any = {};
class FakeLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
return of(translations);
}
}
@Pipe({
name: 'translate'
})
export class TranslatePipeMock implements PipeTransform {
public name = 'translate';
public transform(query: string, ...args: any[]): any {
return query;
}
}
@Injectable()
export class TranslateServiceStub {
public get<T>(key: T): Observable<T> {
return of(key);
}
}
@NgModule({
declarations: [
TranslatePipeMock
],
providers: [
{ provide: TranslateService, useClass: TranslateServiceStub },
{ provide: TranslatePipe, useClass: TranslatePipeMock },
],
imports: [
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: FakeLoader },
})
],
exports: [
TranslatePipeMock,
TranslateModule
]
})
export class TranslateTestingModule {
} |
Has this testing module been integrated into the library? Or will it be? |
@AndreiShostik Note: If I turn Angular Ivy off, the module works. |
Hello there. One guy in my team used a mocked class and a spy. The lines with the '<====' are the most important ones. Works for Angular 8 and 9 The mocked class: i18n.pipe.mock.ts
Test spec to your Component "PageErrorMessageComponent", here: page-error-message.component.spec.ts for Example. PageErrorMessageComponent´s template uses I18 Pipe.
|
Does anyone try it and confirm that it works? |
The next code works fine for me: import { NgModule } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
@NgModule({
imports: [
TranslateModule.forRoot()
],
exports: [
TranslateModule
]
})
export class TranslateTestingModule {
} Then simple import it TestBed.configureTestingModule({
declarations: [...]
imports: [
TranslateTestingModule
]
}); |
Hello @Ks89 and everyone. You can try ngx-translate-testing package to see if you can figure out with your problem. But you need to upgrade your project Angular version to at least version 6 as said in Installation section. |
I am coming quite late on this question but you can just |
I'm submitting a ... (check one with "x")
Question
How to test a component that uses TranslateService and the translate pipe?
I have a root module with:
also, inside my main component (with router-outlet) I have:
and finally, in my Component that I want to test I have this:
Now I want to test 'AboutComponent'. But how?
At the moment I have this:
Obviously I have to say to my test that I'm using 2 languages (en and it), but I don't know which is the right way to do that.
At the moment both TemplateService and pipes aren't working.
For instance, I created this to test the result of a traslate pipe:
and the result is this error:
Thank u.
Please tell us about your environment:
ngx-translate version: 7.2.0
Angular version: 4.3.4
Browser: [all]
The text was updated successfully, but these errors were encountered: