How to mock Image object with Karma (Angular 7)?
I'm trying to mock the default DOM Image
object for unit testing an Angular service.
The service is simple, it checks the "webP" format support :
import {Injectable} from '@angular/core';
import {Promise} from 'es6-promise';
import {environment} from '../../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class AppLoadService {
constructor() {
}
initializeApp(): Promise<any> {
return new Promise((resolve) => {
console.log(`initializeApp:: inside promise`);
if (typeof Image === 'undefined') {
console.log(`initializeApp:: Image undefined`);
resolve();
return;
}
const webP = new Image();
webP.onload = () => {
console.log(`initializeApp:: WebP support: true`);
environment.webP = true;
resolve();
};
webP.onerror = () => {
console.log(`initializeApp:: WebP support: false`);
resolve();
};
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
}
I found a way to check the webP support (default in chromium where Karma is running), and a way to check fallback on Image undefined
.
But I cannot find a way to checks the onerror
fallback...
Here is my spec file :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
import {environment} from '../../../../environments/environment';
describe('AppLoadService', () => {
let service: AppLoadService;
const originalImage = Image;
beforeEach(() => TestBed.configureTestingModule({}));
beforeEach(() => {
service = TestBed.get(AppLoadService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(true);
done();
});
};
test();
});
it('should resolve without webP (A)', (done) => {
const test = () => {
Image = undefined;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
it('should resolve without webP (B)', (done) => {
// How to force Image to throw "onerror" ?
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
});
The question is on should resolve without webP (B)
test, at the end of the file..
Moreover, is there a better way to check undefined Image object or onload
callback ?
Thanks !
EDIT
Can't get it works as it is, so I change the service constructor to provide "Image" dependency.
constructor(@Inject('Image') image: typeof Image) {
this.image = image;
}
Have to load the module like that :
providers: [
AppLoadService,
// [...]
{provide: 'Image', useValue: Image},
]
And each resolve()
now includes environment.webP
result. Otherwise, individual test are a real pain, environment
is randomly rewritten before being tested.
With a simple Mock it works like this :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
class MockImageFail {
public onerror: Function;
private _src: string;
set src(src) {
this._src = src;
if (this.onerror) {
this.onerror();
}
}
}
describe('AppLoadService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: 'Image', useValue: Image}]
});
});
it('should be created', () => {
const service = TestBed.get(AppLoadService);
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(true);
done();
});
});
it('should not resolve without webP (A)', (done) => {
TestBed.overrideProvider('Image', {useValue: undefined});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
it('should not resolve without webP (B)', (done) => {
TestBed.overrideProvider('Image', {useValue: MockImageFail});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
});
I'm not really happy with that and I'm sure there is another better way :/
angular image dom karma-jasmine angular7
add a comment |
I'm trying to mock the default DOM Image
object for unit testing an Angular service.
The service is simple, it checks the "webP" format support :
import {Injectable} from '@angular/core';
import {Promise} from 'es6-promise';
import {environment} from '../../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class AppLoadService {
constructor() {
}
initializeApp(): Promise<any> {
return new Promise((resolve) => {
console.log(`initializeApp:: inside promise`);
if (typeof Image === 'undefined') {
console.log(`initializeApp:: Image undefined`);
resolve();
return;
}
const webP = new Image();
webP.onload = () => {
console.log(`initializeApp:: WebP support: true`);
environment.webP = true;
resolve();
};
webP.onerror = () => {
console.log(`initializeApp:: WebP support: false`);
resolve();
};
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
}
I found a way to check the webP support (default in chromium where Karma is running), and a way to check fallback on Image undefined
.
But I cannot find a way to checks the onerror
fallback...
Here is my spec file :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
import {environment} from '../../../../environments/environment';
describe('AppLoadService', () => {
let service: AppLoadService;
const originalImage = Image;
beforeEach(() => TestBed.configureTestingModule({}));
beforeEach(() => {
service = TestBed.get(AppLoadService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(true);
done();
});
};
test();
});
it('should resolve without webP (A)', (done) => {
const test = () => {
Image = undefined;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
it('should resolve without webP (B)', (done) => {
// How to force Image to throw "onerror" ?
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
});
The question is on should resolve without webP (B)
test, at the end of the file..
Moreover, is there a better way to check undefined Image object or onload
callback ?
Thanks !
EDIT
Can't get it works as it is, so I change the service constructor to provide "Image" dependency.
constructor(@Inject('Image') image: typeof Image) {
this.image = image;
}
Have to load the module like that :
providers: [
AppLoadService,
// [...]
{provide: 'Image', useValue: Image},
]
And each resolve()
now includes environment.webP
result. Otherwise, individual test are a real pain, environment
is randomly rewritten before being tested.
With a simple Mock it works like this :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
class MockImageFail {
public onerror: Function;
private _src: string;
set src(src) {
this._src = src;
if (this.onerror) {
this.onerror();
}
}
}
describe('AppLoadService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: 'Image', useValue: Image}]
});
});
it('should be created', () => {
const service = TestBed.get(AppLoadService);
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(true);
done();
});
});
it('should not resolve without webP (A)', (done) => {
TestBed.overrideProvider('Image', {useValue: undefined});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
it('should not resolve without webP (B)', (done) => {
TestBed.overrideProvider('Image', {useValue: MockImageFail});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
});
I'm not really happy with that and I'm sure there is another better way :/
angular image dom karma-jasmine angular7
add a comment |
I'm trying to mock the default DOM Image
object for unit testing an Angular service.
The service is simple, it checks the "webP" format support :
import {Injectable} from '@angular/core';
import {Promise} from 'es6-promise';
import {environment} from '../../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class AppLoadService {
constructor() {
}
initializeApp(): Promise<any> {
return new Promise((resolve) => {
console.log(`initializeApp:: inside promise`);
if (typeof Image === 'undefined') {
console.log(`initializeApp:: Image undefined`);
resolve();
return;
}
const webP = new Image();
webP.onload = () => {
console.log(`initializeApp:: WebP support: true`);
environment.webP = true;
resolve();
};
webP.onerror = () => {
console.log(`initializeApp:: WebP support: false`);
resolve();
};
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
}
I found a way to check the webP support (default in chromium where Karma is running), and a way to check fallback on Image undefined
.
But I cannot find a way to checks the onerror
fallback...
Here is my spec file :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
import {environment} from '../../../../environments/environment';
describe('AppLoadService', () => {
let service: AppLoadService;
const originalImage = Image;
beforeEach(() => TestBed.configureTestingModule({}));
beforeEach(() => {
service = TestBed.get(AppLoadService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(true);
done();
});
};
test();
});
it('should resolve without webP (A)', (done) => {
const test = () => {
Image = undefined;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
it('should resolve without webP (B)', (done) => {
// How to force Image to throw "onerror" ?
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
});
The question is on should resolve without webP (B)
test, at the end of the file..
Moreover, is there a better way to check undefined Image object or onload
callback ?
Thanks !
EDIT
Can't get it works as it is, so I change the service constructor to provide "Image" dependency.
constructor(@Inject('Image') image: typeof Image) {
this.image = image;
}
Have to load the module like that :
providers: [
AppLoadService,
// [...]
{provide: 'Image', useValue: Image},
]
And each resolve()
now includes environment.webP
result. Otherwise, individual test are a real pain, environment
is randomly rewritten before being tested.
With a simple Mock it works like this :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
class MockImageFail {
public onerror: Function;
private _src: string;
set src(src) {
this._src = src;
if (this.onerror) {
this.onerror();
}
}
}
describe('AppLoadService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: 'Image', useValue: Image}]
});
});
it('should be created', () => {
const service = TestBed.get(AppLoadService);
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(true);
done();
});
});
it('should not resolve without webP (A)', (done) => {
TestBed.overrideProvider('Image', {useValue: undefined});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
it('should not resolve without webP (B)', (done) => {
TestBed.overrideProvider('Image', {useValue: MockImageFail});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
});
I'm not really happy with that and I'm sure there is another better way :/
angular image dom karma-jasmine angular7
I'm trying to mock the default DOM Image
object for unit testing an Angular service.
The service is simple, it checks the "webP" format support :
import {Injectable} from '@angular/core';
import {Promise} from 'es6-promise';
import {environment} from '../../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class AppLoadService {
constructor() {
}
initializeApp(): Promise<any> {
return new Promise((resolve) => {
console.log(`initializeApp:: inside promise`);
if (typeof Image === 'undefined') {
console.log(`initializeApp:: Image undefined`);
resolve();
return;
}
const webP = new Image();
webP.onload = () => {
console.log(`initializeApp:: WebP support: true`);
environment.webP = true;
resolve();
};
webP.onerror = () => {
console.log(`initializeApp:: WebP support: false`);
resolve();
};
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
}
I found a way to check the webP support (default in chromium where Karma is running), and a way to check fallback on Image undefined
.
But I cannot find a way to checks the onerror
fallback...
Here is my spec file :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
import {environment} from '../../../../environments/environment';
describe('AppLoadService', () => {
let service: AppLoadService;
const originalImage = Image;
beforeEach(() => TestBed.configureTestingModule({}));
beforeEach(() => {
service = TestBed.get(AppLoadService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(true);
done();
});
};
test();
});
it('should resolve without webP (A)', (done) => {
const test = () => {
Image = undefined;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
it('should resolve without webP (B)', (done) => {
// How to force Image to throw "onerror" ?
const test = () => {
Image = originalImage;
service.initializeApp().then(() => {
expect(environment.webP).toBe(false);
done();
});
};
test();
});
});
The question is on should resolve without webP (B)
test, at the end of the file..
Moreover, is there a better way to check undefined Image object or onload
callback ?
Thanks !
EDIT
Can't get it works as it is, so I change the service constructor to provide "Image" dependency.
constructor(@Inject('Image') image: typeof Image) {
this.image = image;
}
Have to load the module like that :
providers: [
AppLoadService,
// [...]
{provide: 'Image', useValue: Image},
]
And each resolve()
now includes environment.webP
result. Otherwise, individual test are a real pain, environment
is randomly rewritten before being tested.
With a simple Mock it works like this :
import {TestBed} from '@angular/core/testing';
import {AppLoadService} from './app-load.service';
class MockImageFail {
public onerror: Function;
private _src: string;
set src(src) {
this._src = src;
if (this.onerror) {
this.onerror();
}
}
}
describe('AppLoadService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: 'Image', useValue: Image}]
});
});
it('should be created', () => {
const service = TestBed.get(AppLoadService);
expect(service).toBeTruthy();
});
it('should resolve with webP', (done) => {
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(true);
done();
});
});
it('should not resolve without webP (A)', (done) => {
TestBed.overrideProvider('Image', {useValue: undefined});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
it('should not resolve without webP (B)', (done) => {
TestBed.overrideProvider('Image', {useValue: MockImageFail});
const service = TestBed.get(AppLoadService);
service.initializeApp().then((supportWebP) => {
expect(supportWebP).toBe(false);
done();
});
});
});
I'm not really happy with that and I'm sure there is another better way :/
angular image dom karma-jasmine angular7
angular image dom karma-jasmine angular7
edited Nov 15 '18 at 10:35
Goncalo Peres
1,4541519
1,4541519
asked Nov 13 '18 at 9:07
DoubidouDoubidou
453417
453417
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277359%2fhow-to-mock-image-object-with-karma-angular-7%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277359%2fhow-to-mock-image-object-with-karma-angular-7%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown