Closed zj8487 closed 9 years ago
哪里的测试用例?
@fantasyni 我自己项目的测试用例。 你可以用bearcat-dao测试。 我升级前都是ok的。升级后全部不过。
这里 bearcat 哪里来的
before(function(done) {
bearcat.start(function() {
done();
});
});
每个测试文件的初始化部分
"use strict";
var path = require('path');
var should = require('should');
var assert = require("assert");
var Bearcat = require('bearcat');
describe('xxx Test', function(){
var contextPath = require.resolve('../../../contextTest.json');
var paths = [contextPath];
var bearcat = Bearcat.createApp(paths);
before(function(done) {
bearcat.start(function() {
done();
});
});
因为 bearcat 文件 是 require 进来的,是单例的,这个就是共享的,在同一个进程里面
所以每次在一个文件用完之后要 bearcat.stop() 一下才行
或者在 bearcat.createApp 之前执行下 bearcat.stop() 清理一下 require('bearcat') 的状态
Bearcat.createApp = function(configLocations, opts) {
if (this.state >= STATE_INITED) {
return Bearcat;
}
改成这样子报错还是一样吗?
错误不一样了。报错:所以getBean() 出来的对象都是null
我现在的项目都是有一个 after 的
这个其实就是 require 在单元测试里的坑
after(function(done) {
bearcat.stop();
done();
});
我改了试一试。 但是建议还是和以前保持一致,这样的话新手面对的坑少些。也更方便
恩,我大概知道了,我等下发个版本
Bearcat.createApp = function(configLocations, opts) {
if (this.state >= STATE_INITED) {
Bearcat.stop();
}
}
改成这样子试试 把 bearcat.js 里面
好的
改成Bearcat.stop();
后还是报错:getBean() 出来的对象都是null
晕,有什么日志输出吗?
[2015-02-13 19:28:00.289] [ERROR] bearcat - [BeanFactory] BeanFactory beanDefinition null for
这个不科学啊,bearcat-dao我试了已经可以了
logger.info('Bearcat startup in %s with %s ms', env, Date.now() - self.startTime);
这句话输出了吗
bearcat-dao 使用了$xx这种注入吗?
这是第一个错误的stack
at null.aaa (/home/xxxxx/app/util/xxx.js:26:39)
at Object.MetaUtil.resolveFuncAnnotation (/home/xxxxx/node_modules/bearcat/lib/util/metaUtil.js:89:24)
at MetaLoader.loadFile (/home/xxxxx/node_modules/bearcat/lib/resource/metaLoader.js:87:19)
at MetaLoader.loadPath (/home/xxxxx/node_modules/bearcat/lib/resource/metaLoader.js:137:12)
at MetaLoader.load (/home/xxxxx/node_modules/bearcat/lib/resource/metaLoader.js:51:7)
at ConfigLoader.getResources (/home/xxxxx/node_modules/bearcat/lib/resource/configLoader.js:61:14)
at ResourceLoader.load (/home/xxxxx/node_modules/bearcat/lib/resource/resourceLoader.js:61:43)
at ApplicationContext.getResource (/home/xxxxx/node_modules/bearcat/lib/context/applicationContext.js:153:29)
at ApplicationContext.refreshBeanFactory (/home/xxxxx/node_modules/bearcat/lib/context/applicationContext.js:332:39)
at ApplicationContext.refresh (/home/xxxxx/node_modules/bearcat/lib/context/applicationContext.js:201:7)
at EventEmitter.Bearcat.start (/home/xxxxx/node_modules/bearcat/lib/bearcat.js:137:26)
at Context.<anonymous> (/home/xxxxx/test/qqq/xxx/xxxxManagerTest.js:16:17)
at Hook.Runnable.run (/home/xxxxx/node_modules/mocha/lib/runnable.js:218:15)
at Hook.Runnable.run (/home/xxxxx/node_modules/bluebird-mocha-generators/index.js:12:14)
at next (/home/xxxxx/node_modules/mocha/lib/runner.js:259:10)
at Immediate._onImmediate (/home/xxxxx/node_modules/mocha/lib/runner.js:276:5)
at processImmediate [as _immediateCallback] (timers.js:321:17)
ok thx 有堆栈我再仔细看看
你那个bean咋写的能示例贴一下吗?混淆一下变量名
"use strict";
var Promise = require("bluebird");
var XXXXUtil = function() {
this.$id = "xxxxUtil";
this.$requireUtil = null;
this._publicXX = null;
}
function defineGetter(key, getFunction) {
Object.defineProperty(XXXXUtil.prototype, key, {
configurable: false,
enumerable: true,
get: getFunction
});
};
defineGetter("publicXX", function () {
if (this._publicXX) return this._publicXX;
this._publicXX = this.$requireUtil.ip.address("public"); // this.$requireUtil is null
if (this._publicXX == "127.0.0.1") {
this._publicXX = this.$requireUtil.ip.address("private");
}
return this._publicXX;
});
module.exports = XXXXUtil
你试试在 bearcat/lib/util/metaUtil.js 里面的89行后面加入看看
if (Utils.checkFunction(value)) {
continue;
}
for (var funcKey in funcProps) {
var value = funcProps[funcKey];
if (Utils.checkFunction(value)) {
continue;
}
if (MetaUtil.checkFuncAnnotation(funcKey)) {
var key = funcKey.substr(1);
if (MetaUtil.checkInMetaProps(funcKey)) {
if (key === Constant.META_AOP && funcProps[funcKey] === true) {
meta[key] = this.resolvePrototypeAnnotation(func);
} else {
meta[key] = funcProps[funcKey];
}
} else {
if (!MetaUtil.checkInFuncArgs(funcKey, funcArgs)) {
if (MetaUtil.checkFuncPropsValue(funcKey)) {
props.push({
name: funcKey,
value: value
});
} else if (MetaUtil.checkFuncPropsType(funcKey)) {
props.push({
name: funcKey,
type: value
});
} else if (MetaUtil.checkFuncPropsNamespace(funcKey)) {
props.push({
name: funcKey,
ref: value
});
} else {
props.push({
name: funcKey,
ref: key
});
}
}
}
} else if (MetaUtil.checkFuncPropsConfigValue(value)) {
props.push({
name: funcKey,
value: value
});
}
}
89行后面不对吧。是89行就出错了啊。 加了,错误一样,堆栈一样
恩,我自己也复现了,应该是你用了 defineProperty 导致的 取出元素来就执行了 get 方法,而这时其实 this.$xxx 还没好
如何解决呢?
你这个是修改了默认的 get set 方法,有点坑啊,之前的版本没问题,是因为之前bearcat是通过解析function构造函数做字符串解析的,现在是通过 new function 构造函数来拿到里面的 $xxx 属性,这样子一来你这种情况就会有这么个问题
那就是我这种写法不支持?
要支持只能
for (var funcKey in funcProps) {
try{
var value = funcProps[funcKey];
}catch(e) {
}
}
这样子捕捉异常,但是这样一来又有性能损失
之所以改成 new 的方式,因为这样子可以更加灵活
可以支持这样的
var Car = function() {
this.$id = "car";
this["$engine"] = null; // use []
var wheelName = "$wheel";
this[wheelName] = null; // use variable
};
Car.prototype["$light"] = null; // use variable in prototype
Car.prototype.run = function() {
this.$engine.run();
this.$light.shine();
this.$wheel.run();
console.log('car run...');
}
module.exports = Car;
但是在对象上进行getter, setter也是很常见啊 还能有什么其他办法吗?
目前只能加个 createApp 参数,强制使用 第一种通过解析构造函数字符串的形式来做
我再想想其它办法,感谢提出
好的,多谢,辛苦了
你先看看其他办法吧,我先降级就是了。 不用添加临时处理办法
我找到了方法,能规避你这种情况,就是直接忽视 prototype 里面定义的属性
for (var funcKey in funcProps) {
if (!funcProps.hasOwnProperty(funcKey)) {
continue;
}
}
那唯一的漏洞就是 definePropery 到 this ,貌似没有人这么干吧,那样写法一般是
var a = {}
Object.defineProperty(a, 'b', {});
试试 bearcat@0.3.17 版本哈
define 到this的为什么不能忽略?
不好消息,0.3.17有两个case跑不过,是关于collections这个库的。0.2.x可以。 不知道是bearcat修改的影响还是collections的bug
@fantasyni 这样改有问题。 这样改了后我如下代码不工作了,这个应该和库没关系。
"use strict";
var Shim = require("collections/shim");
var array = require("collections/shim-array");
var util = require('util');
var Type = function(value, name) {
this.value = Number(value);
this.name = String(name);
};
Type.prototype.valueOf = function() {
return this.value;
};
Type.prototype.toString = function() {
return util.format('[%s|%d]', this.name, this.value);
};
var testObject = {
"aa": new Type(0, "aa"),
"bb": new Type(1, "bb"),
"cc": new Type(2, "cc"),
"dd": new Type(3, "dd"),
"ee": new Type(4, "ee"),
"ff": new Type(5, "ff"),
"gg": new Type(6, "gg"),
"hh": new Type(7, "hh"),
"ii": new Type(8, "ii"),
"jj": new Type(9, "jj"),
"kk": new Type(10, "kk"),
};
var GGGGG = function() {
this.$id = "ggggg";
this.FUCK = testObject;
this.FUCK.sortedLists = Object.values(testObject).sort(Object.compare);
// 上面这行会报错。之前版本没问题。把这行移出去到外面也不报错。
};
module.exports = GGGGG;
找到原因了,是因为
Object.values(testObject).sort(Object.compare);
会把 testObject 对象给改变了
一般在构造函数里面是不做初始化逻辑的,如果有这个需求,可以放在 bearcat 提供的 init 方法里面,也是一样的效果,构造函数就是用来定义属性、依赖关系、配置信息
我更新个版本,可以强制指定使用解析构造函数字符串的形式吧
这样子的写法,new 多次就会复现一样的错误
一个文件内的全局变量很坑的,尽量避免
"use strict";
var Shim = require("collections/shim");
var array = require("collections/shim-array");
var util = require('util');
var Type = function(value, name) {
this.value = Number(value);
this.name = String(name);
};
Type.prototype.valueOf = function() {
return this.value;
};
Type.prototype.toString = function() {
return util.format('[%s|%d]', this.name, this.value);
};
var testObject = {
"aa": new Type(0, "aa"),
"bb": new Type(1, "bb"),
"cc": new Type(2, "cc"),
"dd": new Type(3, "dd"),
"ee": new Type(4, "ee"),
"ff": new Type(5, "ff"),
"gg": new Type(6, "gg"),
"hh": new Type(7, "hh"),
"ii": new Type(8, "ii"),
"jj": new Type(9, "jj"),
"kk": new Type(10, "kk"),
};
var GGGGG = function() {
this.$id = "ggggg";
this.FUCK = testObject;
this.FUCK.sortedLists = Object.values(testObject).sort(Object.compare);
// 上面这行会报错。之前版本没问题。把这行移出去到外面也不报错。
};
module.exports = GGGGG;
new GGGGG();
new GGGGG();
ok, 我改改,你打算怎么做?
建议在bearcat使用说明中或,强行限制
一般在构造函数里面是不做初始化逻辑的
那上面的Type类型定义有问题没有?
一个文件内的全局变量很坑的,尽量避免
定义是可以的,但是实例对象(使用匿名对象)是有问题的,这样代码热更新也是不支持的,尽量写成无状态的吧,我等下发个版本
讨论个bearcat最佳实践问题: 你觉得Type定义是专门写个bean好还是就这样好?
建议做个限制,在构造函数中都不允许初始化,强制到init中。你看看是否可行?
0.4.x大概好久发布?
这个有无说明?
bearcat@0.3.18 已经自己做了处理,不 new 来获取依赖关系,但是要配置一下
_All testcases say an error:_
_error is throw from bearcat.start() in every testcase file_
_I noticed that the Bearcat.createApp has been changed_
_I tried change the code as follow but it fails too._
_you can use bearcat-dao to test after updating the bearcat_