我正在使用Jasmine BDD Javascript库并且非常享受它。我有我想要重用的测试代码(例如,测试基类的多个实现或在稍微不同的上下文中运行相同的测试)并且我不确定如何使用Jasmine来完成它。我知道我可以将代码从jasmine函数移到可重用的类中,但我喜欢代码读取散布Jasmine函数的方式(描述,它),我不想将规范与测试代码分开,除非我不得不。有没有人使用Jasmine遇到这个问题,你是如何处理它的?
答案 0 :(得分:28)
以下是Pivotal Labs的一篇文章,其中详细介绍了如何打包描述调用:
DRYing up Jasmine Specs with Shared Behavior
显示部分包装函数的文章中的片段:
function sharedBehaviorForGameOf(context) {
describe("(shared)", function() {
var ball, game;
beforeEach(function() {
ball = context.ball;
game = context.game;
});
});
}
答案 1 :(得分:11)
我不确定@ starmer的解决方案是如何运作的。正如我在评论中提到的,当我使用他的代码时,context
总是未定义的。
相反,你需要做的事情(正如@moefinley所提到的)是传递对构造函数的引用。我使用一个例子概述了这种方法written a blog post。这就是它的本质:
describe('service interface', function(){
function createInstance(){
return /* code to create a new service or pass in an existing reference */
}
executeSharedTests(createInstance);
});
function executeSharedTests(createInstanceFn){
describe('when adding a new menu entry', function(){
var subjectUnderTest;
beforeEach(function(){
//create an instance by invoking the constructor function
subjectUnderTest = createInstanceFn();
});
it('should allow to add new menu entries', function(){
/* assertion code here, verifying subjectUnderTest works properly */
});
});
}
答案 2 :(得分:2)
关于butbot的网站上有一篇很好的文章:https://robots.thoughtbot.com/jasmine-and-shared-examples
这是一个简短的样本:
appNamespace.jasmine.sharedExamples = {
"rectangle": function() {
it("has four sides", function() {
expect(this.subject.sides).toEqual(4);
});
},
};
使用一些下划线函数来定义itShouldBehaveLike
window.itShouldBehaveLike = function() {
var exampleName = _.first(arguments),
exampleArguments = _.select(_.rest(arguments), function(arg) { return !_.isFunction(arg); }),
innerBlock = _.detect(arguments, function(arg) { return _.isFunction(arg); }),
exampleGroup = appNamespace.jasmine.sharedExamples[exampleName];
if(exampleGroup) {
return describe(exampleName, function() {
exampleGroup.apply(this, exampleArguments);
if(innerBlock) { innerBlock(); }
});
} else {
return it("cannot find shared behavior: '" + exampleName + "'", function() {
expect(false).toEqual(true);
});
}
};
答案 3 :(得分:1)
这与starmer的答案类似,但经过一番努力后,我发现了一些不同之处。缺点是,如果规范失败,您只需看到“应遵守常见的保存规范”。在Jasmine报告中。堆栈跟踪是查找失败位置的唯一方法。
// common specs to execute
self.executeCommonSpecifications = function (vm) {
// I found having the describe( wrapper here doesn't work
self.shouldCallTheDisplayModelsSaveMethod(vm);
}
self.shouldCallTheDisplaysSaveMethod = function (vm) {
expect(vm.save.calls.count()).toBe(1);
};
// spec add an it so that the beforeEach is called before calling this
beforeEach(function(){
// this gets called if wrapped in the it
vm.saveChanges();
}
it('should adhere to common saving specifications', function () {
executeSavingDisplaysCommonSpecifications(vm);
});
答案 4 :(得分:1)
这是我采取的方法,受到本文的启发:
https://gist.github.com/traviskaufman/11131303
基于Jasmine自己的文档:
http://jasmine.github.io/2.0/introduction.html#section-The_%3Ccode%3Ethis%3C/code%3E_keyword
通过将共享依赖项设置为beforeEach
函数原型的属性,您可以扩展beforeEach
以通过this
使这些依赖项可用。
示例:
describe('A suite', function() {
// Shared setup for nested suites
beforeEach(function() {
// For the sake of simplicity this is just a string
// but it could be anything
this.sharedDependency = 'Some dependency';
});
describe('A nested suite', function() {
var dependency;
beforeEach(function() {
// This works!
dependency = this.sharedDependency;
});
it('Dependency should be defined', function() {
expect(dependency).toBeDefined();
});
});
describe('Check if string split method works', function() {
var splitToArray;
beforeEach(function() {
splitToArray = this.sharedDependency.split();
});
it('Some other test', function() { ... });
});
});
我知道我的例子有点无用但它应该用作代码示例。
当然,这只是你可以做的很多事情之一,你可以做到这一点,我确信更复杂的设计模式可以应用于顶部或旁边。
希望它有所帮助!
答案 5 :(得分:0)
让我用工作示例进行总结
describe('test', function () {
beforeEach(function () {
this.shared = 1;
});
it('should test shared', function () {
expect(this.shared).toBe(1);
});
testShared();
});
function testShared() {
it('should test in function', function() {
expect(this.shared).toBe(1);
});
}
这里的关键部分是这个关键字来传递上下文,因此,我们必须使用“常规”功能(另一个关键部分)。
对于生产代码,我可能只在beforeEach
中使用常规函数来传递/提取上下文,但为了简洁起见,在规范中继续使用箭头功能。
将上下文作为参数传递是行不通的,因为通常情况下,我们在之后调用的beforeEach
块中定义上下文。
具有describe
部分似乎并不重要,但仍然欢迎其具有更好的结构
答案 6 :(得分:0)
这是一个更简单的解决方案。 声明变量函数并使用它,而不使用this关键字或上下文:
describe("Test Suit", function ()
{
var TestCommonFunction = function(inputObjects)
{
//common code here or return objects and functions here etc
};
it("Should do x and y", function()
{
//Prepare someInputObjects
TestCommonFunction(someInputObjects);
//do the rest of the test or evaluation
});
});
您还可以返回具有更多功能的对象,然后调用返回的功能。
答案 7 :(得分:-10)
有人指出我将一个describe调用包装在一个传递参数的函数中。