我正在尝试学习如何使用Jasmine和Sinon来测试Backbone应用程序,我正在学习本教程.然而,我遇到了一个我不知道如何解决的问题.
最有可能解决方案很简单,但我需要一些指导......
在我的project.spec.js文件中,这是给出问题的代码:
it("should not save when name is empty", function() {
var eventSpy = sinon.spy();
this.project.bind("error", eventSpy);
this.project.save({"name": ""});
expect(this.eventSpy.calledOnce).toBeTruthy();
expect(this.eventSpy.calledWith(
this.project,
"cannot have an empty name"
)).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)
这是在浏览器中可以看到的特定错误:
Failing 1 spec
7 specs | 1 failing
Project model should not save when name is empty.
TypeError: Object #<Object> has no method 'spy'
TypeError: Object #<Object> has no method 'spy'
at null.<anonymous> (http://localhost:8888/__spec__/models/project.spec.js:53:26)
at jasmine.Block.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1024:15)
at jasmine.Queue.next_ (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2025:31)
at jasmine.Queue.start (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:1978:8)
at jasmine.Spec.execute (http://localhost:8888/__JASMINE_ROOT__/jasmine.js:2305:14)
at …Run Code Online (Sandbox Code Playgroud) 我想测试我的函数对另一个函数的调用,特别是一个对象的参数.
问题是sinon.js似乎存储了对其arguments数组中给出的object参数的引用,这自然是预期的.但是,当参数稍后由ref修改时会产生问题,这会在调用函数时更改这些参数的表观值.
对这种情况进行单元测试的最佳方法是什么?
这是一个人为的例子:
var view = Backbone.View.extend({
initialize: function () {
_.bindAll(this);
},
dostuff: function () {
var coords = { x: 0, y: 0 };
for (var i = 0; i < 10; i++) {
this.otherstuff(coords);
coords.x += 10;
}
},
otherstuff: function (coord) {
// Stubbed
}
});
test("a test", function() {
// Arrange
var blah = new view();
sinon.stub(blah, 'otherstuff');
// Act
blah.dostuff();
// Assert
var expectedFirstCallCoords = { x: 0, y: 0 …Run Code Online (Sandbox Code Playgroud) 对于下面的代码片段nodejs,我将如何send使用proxyquire和存根该方法sinon,因为它属于文件index.js?我尝试了很多方法,但经常出错.
var emailjs = require("emailjs");
emailjs.server.connect({
user: obj.user,
password: obj.password,
host: obj.host,
port: obj.port,
tls: obj.tls,
ssl: obj.ssl
})
.send(mailOptions, function(error, message){
if (error) {
console.log("ERROR");
context.done(new Error("There was an error sending the email: %s", error));
return;
} else {
console.log("SENT");
context.done();
return;
}
});
Run Code Online (Sandbox Code Playgroud)
到目前为止,在我的测试中,我有以下设置,但得到Uncaught TypeError: Property 'connect' of object #<Object> is not a function.
readFileStub = sinon.stub();
sendStub = sinon.stub();
connectStub = sinon.stub().returns(sendStub);
testedModule = proxyquire('../index', …Run Code Online (Sandbox Code Playgroud) 我正在编写一个角度控制器,它对数据服务有依赖性(数据服务转到http服务器),我想模仿它的行为.
我正在使用一个名为bard js的库进行模拟,它有一个名为bard.mockService的模拟服务api .
在beforeEach语句中,我正在做:
beforeEach(function() {
bard.appModule('app.process.creation');
bard.inject('$controller', '$rootScope', '$q', 'processCreationDataservice');
bard.mockService(processCreationDataservice, {
createProcess: $q.when({}),
_default: $q.when([])
});
controller = $controller('ProcessCreationController');
$rootScope.$apply();
});
Run Code Online (Sandbox Code Playgroud)
然后我的测试:
it('should call create process data service to create process', function() {
controller.create();
expect(processCreationDataservice.createProcess).to.have.been.calledOnce;
});
Run Code Online (Sandbox Code Playgroud)
正如您在测试中看到的那样,我想声明dataservice.createProcess被调用一次.
控制器没有调用方法processCreationDataservice.createProcess,仍然测试正在通过.
(function() {
angular
.module('app.process.creation')
.controller('ProcessCreationController', ProcessCreationController);
ProcessCreationController.$inject = ['processCreationDataservice'];
function ProcessCreationController(processCreationDataservice) {
var vm = this;
vm.process = {
name: '',
bankId: ''
};
vm.create = function() {
};
}})();
Run Code Online (Sandbox Code Playgroud)
我想知道为什么这个测试正在通过,我该怎么做才能断言该方法被调用一次.
我按照这些说明操作:https: //github.com/wardbell/bardjs#mockService
我正在制作一个使用JWT进行身份验证的REST API,但为了测试我的端点,我想模拟验证JWT的中间件.
我已经定义了一个用于检查令牌的中间件:
// middlewares/auth.js
nJwt = require('njwt');
nconf = require('nconf');
module.exports = {
verifyToken: function(req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
nJwt.verify(token, nconf.get("auth:secret"), function(err, verifiedJwt) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for …Run Code Online (Sandbox Code Playgroud) 我似乎无法从 NodeJS 核心在 fs 上存根 readFileSync。以下代码隔离了该问题。通过 Mocha 运行测试结果如下:
> mocha tests/test.js
Some description
1) "before all" hook
0 passing (15ms)
1 failing
1) Some description "before all" hook:
TypeError: Cannot read property 'charCodeAt' of undefined
at Object.stripBOM (internal/module.js:48:14)
at Object.require.extensions.(anonymous function) (node_modules/proxyquire/lib/proxyquire.js:276:43)
at Proxyquire._withoutCache (node_modules/proxyquire/lib/proxyquire.js:179:12)
at Proxyquire.load (node_modules/proxyquire/lib/proxyquire.js:136:15)
at Context.<anonymous> (tests/test.js:12:15)
Run Code Online (Sandbox Code Playgroud)
这是测试/test.js
var proxyquire = require('proxyquire'),
sinon = require('sinon'),
fs = require('fs'),
sut;
describe('Some description', function () {
var readFileSyncStub;
before(function () {
readFileSyncStub = sinon.stub(fs, 'readFileSync');
readFileSyncStub.withArgs('someFile.js', { encoding: …Run Code Online (Sandbox Code Playgroud) 自 2016 年 3 月以来,javascript/nodejs 的 aws sdk 确实在 AWS.Request链接上提供了 .promise() 方法。
现在我正在 AWS.DynamoDB.DocumentClient(...).get() 方法(它返回一个 AWS.Request 对象)上运行一些单元测试,之后我也调用 .promise() 方法来接收一个 Promise。
现在,当我存根 .get() 方法时,我已经返回了一个 Promise,所以我希望 .promise() 方法只返回我现有的 Promise(通过“返回这个”)。
我的代码就像
var docClient = AWS.DynamoDB.DocumentClient(...)
docClient.get(...).promise().then(...)
Run Code Online (Sandbox Code Playgroud)
和我的测试文件
var docClient = AWS.DynamoDB.DocumentClient(...)
var batchGetStub = sinon.stub(docClient, 'get').callsFake(function(){return Promise.resolve({id:1337})});
// now I need to also stub the .promise() method
var promiseStub = sinon.stub(docClient.get, 'promise').callsFake(functions(){return this}); // just return the promise back
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用,我返回以下错误
类型错误:不能存根不存在的自己的财产承诺
我想我不知何故需要在我的假函数上声明一个 .promise 方法。
我试过这个:
this.protoype.promise = function(this){return this};
在我的假函数中,但这会抛出
类型错误:无法设置未定义的属性“承诺”
我的 componentDidMount 中有一个操作,它在 30000 毫秒后从 Reddit 获取图像。我想测试这个但无法弄清楚?!?!有什么建议?
componentDidMount() {
this.getHumorEvery(30000)
}
getHumorEvery = async (ms) => {
await this.props.getHumor()
return setInterval(() => {
this.props.getHumor()
}, ms)
Run Code Online (Sandbox Code Playgroud)
所以 getHumor() 立即被调用。然后在 30000 毫秒后再次调用它,依此类推。
然后我的测试...
it('should refetch images every 30000 ms', () => {
const clock = sinon.useFakeTimers();
const getHumorSpy = sinon.spy();
renderComponent(requiredProps({ getHumor: getHumorSpy }));
clock.tick(30000)
sinon.assert.calledTwice(getHumorSpy)
Run Code Online (Sandbox Code Playgroud)
})
测试失败,因为 getHumor 只被调用一次。setInterval() 永远不会被解雇?
我想模拟节点模块中函数的结果,以便我可以运行断言。考虑以下节点模块:
const doPostRequest = require('./doPostRequest.js').doPostRequest;
const normalizeSucessResult = require('./normalizer.js').normalizeSucessResult;
const normalizeErrorResult = require('./normalizer.js').normalizeErrorResult;
exports.doPost = (params, postData) => {
return doPostRequest(params, postData).then((res) => {
const normalizedSuccessResult = normalizeSucessResult(res);
return normalizedSuccessResult;
}).catch((err) => {
const normalizedErrorResult = normalizeErrorResult(err);
return normalizedErrorResult;
})
}
Run Code Online (Sandbox Code Playgroud)
该函数doPostRequest返回一个承诺。我如何伪造这个承诺的返回值,以便我可以断言是否normalizeSucessResult已被调用?所以我已经尝试过:
const normalizeSucessResult = require('./normalizer.js');
const doPostRequest = require('./doPostRequests.js');
const doPost = require('./doPost.js');
it('runs a happy flow scenario', async () => {
let normalizeSucessResultStub = sinon.stub(normalizeSucessResult, 'normalizeSucessResult');
let postData = { body: 'Lorum ipsum' }; …Run Code Online (Sandbox Code Playgroud) 最后一天我一直被困在这个问题上,我决定需要帮助。我有以下 javascript 类方法,我正在为其编写单元测试:
getUser = function(req, res){
return new Promise(function(resolve, reject){
User.getByUserId(user_id, function(err, user){
if (err){
return reject({ message: defaultErrorMessage })
} else {
return user ? resolve() : reject({ message: 'The specified user does not exist.' })
}
})
}).then(function(){
....Promise Chain Continues...
})
Run Code Online (Sandbox Code Playgroud)
本质上,我试图做的是编写一个单元测试,用以下内容存根 User.getByUserId mongoose 调用:
let resolvedPromise = sinon.stub().resolves();
sinon.stub(User,'getByUserId').returns(resolvedPromise);
Run Code Online (Sandbox Code Playgroud)
我的想法是,我想删除查找用户并返回已解决的承诺的数据库调用,以便承诺链可以继续,但是我当前的解决方案不允许承诺链继续。
我如何在承诺中包含 sinon 存根并让该存根返回一个 resolve() 以允许承诺链继续?帮助将不胜感激!
sinon ×10
node.js ×5
unit-testing ×4
javascript ×3
mocking ×2
proxyquire ×2
angularjs ×1
asynchronous ×1
aws-sdk ×1
backbone.js ×1
bardjs ×1
chai ×1
express ×1
jasmine ×1
jquery ×1
mocha.js ×1
promise ×1
qunit ×1
reactjs ×1
setinterval ×1
testing ×1