how to fix 404 warnings for images during karma unit testing

房东的猫 提交于 2019-11-27 11:37:46

That is because you need to configurate karma to load then serve them when requested ;)

In your karma.conf.js file you should already have defined files and/or patterns like :

// list of files / patterns to load in the browser
files : [
  {pattern: 'app/lib/angular.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/angular-*.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'app/js/**/*.js', watched: true, included: true, served: true},
  // add the line below with the correct path pattern for your case
  {pattern: 'path/to/**/*.png', watched: false, included: false, served: true},
  // important: notice that "included" must be false to avoid errors
  // otherwise Karma will include them as scripts
  {pattern: 'test/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'test/unit/**/*.js', watched: true, included: true, served: true},
],

// list of files to exclude
exclude: [

],

// ...

You can have a look here for more info :)

EDIT : If you use a nodejs web-server to run your app, you can add this to karma.conf.js :

proxies: {
  '/path/to/img/': 'http://localhost:8000/path/to/img/'
},

EDIT2 : If you don't use or want to use another server you can define a local proxy but as Karma doesn't provide access to port in use, dynamically, if karma starts on another port than 9876 (default), you will still get those annoying 404...

proxies =  {
  '/images/': '/base/images/'
};

Related issue : https://github.com/karma-runner/karma/issues/872

Tom Elmore

The confusing piece of the puzzle for me was the 'base' virtual folder. If you don't know that needs to be included in the asset paths of your fixtures you will find it hard to debug.

As-per the configuration documentation

By default all assets are served at http://localhost:[PORT]/base/

Note: this may not be true for other versions - I'm on 0.12.14 and it worked for me but the 0.10 docs dont mention it.

After specifying the files pattern:

{ pattern: 'Test/images/*.gif', watched: false, included: false, served: true, nocache: false },

I could use this in my fixture:

<img src="base/Test/images/myimage.gif" />

And I didn't need the proxy at that point.

Based on @glepretre's answer, I've created an empty .png file and added this to the config to hide 404 warnings:

proxies: {
  '/img/generic.png': 'test/assets/img/generic.png'
}
Jakub Żwirko

You can create generic middleware inside your karma.conf.js - bit over the top but did the job for me

First define dummy 1px images (I've used base64):

const DUMMIES = {
  png: {
    base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
    type: 'image/png'
  },
  jpg: {
    base64: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigD//2Q==',
    type: 'image/jpeg'
  },
  gif: {
    base64: 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=',
    type: 'image/gif'
  }
};

Then define middleware function:

function surpassImage404sMiddleware(req, res, next) {
  const imageExt = req.url.split('.').pop();
  const dummy = DUMMIES[imageExt];

  if (dummy) {
    // Table of files to ignore
    const imgPaths = ['/another-cat-image.png'];
    const isFakeImage = imgPaths.indexOf(req.url) !== -1;

    // URL to ignore
    const isCMSImage = req.url.indexOf('/cms/images/') !== -1;

    if (isFakeImage || isCMSImage) {
      const img = Buffer.from(dummy.base64, 'base64');
      res.writeHead(200, {
        'Content-Type': dummy.type,
        'Content-Length': img.length
      });
      return res.end(img);
    }
  }
  next();
}

Apply middleware in your karma conf

{
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    middleware: ['surpassImage404sMiddleware'],
    plugins: [
      ...
      {'middleware:surpassImage404sMiddleware': ['value', surpassImage404sMiddleware]}
    ],
    ...
}

If you have root path somewhere in your configuration file you can also use something like this:

proxies: {
  '/bower_components/': config.root + '/client/bower_components/'
}

To fix, in your karma.conf.js make sure to point to the served file with your proxies:

files: [
  { pattern: './src/img/fake.jpg', watched: false, included: false, served: true },
],
proxies: {
  '/image.jpg': '/base/src/img/fake.jpg',
  '/fake-avatar': '/base/src/img/fake.jpg',
  '/folder/0x500.jpg': '/base/src/img/fake.jpg',
  '/undefined': '/base/src/img/fake.jpg'
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!