我正在使用 grunt/karma/phantomjs/jasmine 对我的指令之一(angularjs)进行单元测试。我的测试运行良好
describe('bar foo', function () {
beforeEach(inject(function ($rootScope, $compile) {
elm = angular.element('<img bar-foo src="img1.png"/>');
scope = $rootScope.$new();
$compile(elm)();
scope.$digest();
}));
....
});
但我确实收到了这些 404
WARN [web-server]: 404: /img1.png
WARN [web-server]: 404: /img2.png
...
虽然它们什么也没做,但它们确实给日志输出增加了噪音。有办法解决这个问题吗? (当然不改变 karma 的 logLevel,因为我确实想看到它们)
那是因为您需要配置 karma 来加载,然后在请求时提供服务;)
在您的 karma.conf.js 文件中,您应该已经定义了文件和/或模式,例如:
// 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: [
],
// ...
您可以查看这里以获取更多信息:)
编辑:如果您使用nodejs网络服务器来运行您的应用程序,您可以将其添加到karma.conf.js:
proxies: {
'/path/to/img/': 'http://localhost:8000/path/to/img/'
},
编辑2:如果您不使用或想要使用其他服务器,您可以定义本地代理,但由于 Karma 不会动态地提供对正在使用的端口的访问,如果 karma 在 9876(默认)之外的另一个端口上启动,你仍然会收到那些烦人的 404...
proxies = {
'/images/': '/base/images/'
};
令我困惑的是“基本”虚拟文件夹。如果您不知道需要将其包含在灯具的资源路径中,您会发现很难调试。
按照 配置文档
默认情况下,所有资产均在 http://localhost:[PORT]/base/
提供
注意:这对于其他版本可能不是这样 - 我使用的是 0.12.14,它对我有用,但 0.10 文档没有提到它。
指定文件模式后:
{ pattern: 'Test/images/*.gif', watched: false, included: false, served: true, nocache: false },
我可以在我的装置中使用它:
<img src="base/Test/images/myimage.gif" />
那时我不需要代理。
您可以在 karma.conf.js 中创建通用中间件 -有点过头了,但对我来说已经完成了工作
首先定义虚拟 1px 图像(我使用了 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'
}
};
然后定义中间件函数:
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();
}
在您的 karma conf 中应用中间件
{
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
middleware: ['surpassImage404sMiddleware'],
plugins: [
...
{'middleware:surpassImage404sMiddleware': ['value', surpassImage404sMiddleware]}
],
...
}
根据@glepretre的回答,我创建了一个空的.png文件并将其添加到配置中以隐藏404警告:
proxies: {
'/img/generic.png': 'test/assets/img/generic.png'
}
尽管这是一个旧线程,但我花了几个小时才真正让我的形象真正从业力中得到服务,以消除 404。评论不够彻底。我相信我可以用这个屏幕截图阐明解决方案。本质上,许多评论遗漏的一件事是 proxy 值必须以“/base”开头,即使 base 不在我的任何文件夹路径中,也不在我的请求中。
(没有正斜杠的“base”导致 karma 返回 400 BAD REQUEST)
现在运行 ng test 后,我可以从以下网址成功提供“./src/assets/favicon.png”: http://localhost:9876/test/dummy.png
在我的项目中,我使用以下 npm 包版本:
要修复,请在
karma.conf.js
中确保使用代理指向所提供的文件:
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'
}
如果您在测试中对图像使用假 URL,则可以编写一个自定义中间件函数来返回
200
以“$”开头的 URL,取自 Angular 自己的 karma.conf.js
:
karma.conf.js
module.exports = function (config) {
config.set({
middleware: ['fake-url'],
plugins: [
// ...
{
'middleware:fake-url': [
'factory',
function () {
// Middleware that avoids triggering 404s during tests that need to reference
// image paths. Assumes that the image path will start with `/$`.
// Credit: https://github.com/angular/components/blob/59002e1649123922df3532f4be78c485a73c5bc1/test/karma.conf.js
return function (request, response, next) {
if (request.url.indexOf('/$') === 0) {
response.writeHead(200);
return response.end();
}
next();
};
},
],
},
]
});
}
foo.spec.ts
img.src = '/$/foo.jpg'; // No 404 warning! :-)
如果你的配置文件中有根路径,你也可以使用这样的东西:
proxies: {
'/bower_components/': config.root + '/client/bower_components/'
}
我今天遇到了类似的问题 - 虽然不是最干净的解决方案,但我只是将测试更改为不需要来自本地网络服务器的文件。
即,而不是
elm = angular.element('<img bar-foo src="img1.png"/>');
我已经更改了我的代码以使用
elm = angular.element('<img bar-foo src="https://example.com/img1.png"/>');
Karma 报告的警告来自内置网络服务器,因此如果没有从那里请求文件,也不会显示任何警告。