javascript 在每个套件之前而不是在每个测试之前运行 Mocha 设置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26107027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running Mocha setup before each suite rather than before each test
提问by FuzzyYellowBall
Using NodeJS and Mocha for testing. I think I understand how before() and beforeEach() work. Problem is, I'd like to add a setup script that runs before each "describe" rather than before each "it".
使用 NodeJS 和 Mocha 进行测试。我想我明白 before() 和 beforeEach() 是如何工作的。问题是,我想添加一个在每个“描述”之前而不是在每个“它”之前运行的安装脚本。
If I use before()
it will run only once for the entire suite, and if I use beforeEach()
it will execute before every single test, so I'm trying to find a middle ground.
如果我使用before()
它,整个套件只会运行一次,如果我使用beforeEach()
它,它将在每次测试之前执行,所以我试图找到一个中间立场。
So, if this is my test file:
所以,如果这是我的测试文件:
require('./setupStuff');
describe('Suite one', function(){
it('S1 Test one', function(done){
...
});
it('S1 Test two', function(done){
...
});
});
describe('Suite two', function(){
it('S2 Test one', function(done){
...
});
});
I'd like to have "setupStuff" contain a function that runs before 'Suite one' and 'Suite two'
我想让“setupStuff”包含一个在“套件一”和“套件二”之前运行的函数
Or, in other words, before 'S1 Test one' and 'S2 Test one' but NOT before 'S1 Test two'.
或者,换句话说,在“S1 测试一”和“S2 测试一”之前,而不是“S1 测试二”之前。
Can it be done?
可以做到吗?
采纳答案by Louis
There's no call similar to beforeEach
or before
that does what you want. But it is not needed because you can do it this way:
没有类似于beforeEach
或before
那样的调用可以满足您的需求。但这不是必需的,因为您可以这样做:
function makeSuite(name, tests) {
describe(name, function () {
before(function () {
console.log("shared before");
});
tests();
after(function () {
console.log("shared after");
});
});
}
makeSuite('Suite one', function(){
it('S1 Test one', function(done){
done();
});
it('S1 Test two', function(done){
done();
});
});
makeSuite('Suite two', function(){
it('S2 Test one', function(done){
done();
});
});
回答by ya_dimon
you can also do it in this more flexible way:
你也可以用这种更灵活的方式来做到这一点:
require('./setupStuff');
describe('Suite one', function(){
loadBeforeAndAfter(); //<-- added
it('S1 Test one', function(done){
...
});
it('S1 Test two', function(done){
...
});
});
describe('Suite two', function(){
loadBeforeAndAfter();//<-- added
it('S2 Test one', function(done){
...
});
});
describe('Suite three', function(){
//use some other loader here, before/after, or nothing
it('S3 Test one', function(done){
...
});
});
function loadBeforeAndAfter() {
before(function () {
console.log("shared before");
});
after(function () {
console.log("shared after");
});
}
回答by tul
I have found this approach worked for me, it patches all describe suites.
我发现这种方法对我有用,它修补了所有描述套件。
function suitePatches()
{
before(function()
{
// before suite behaviour
});
after(function()
{
// after suite behaviour
});
}
let origDescribe = describe;
describe = function(n,tests)
{
origDescribe(n,function()
{
suitePatches();
tests.bind(this)();
});
}
let origOnly = origDescribe.only;
describe.only = function(n,tests)
{
origOnly(n,function()
{
suitePatches();
tests.bind(this)();
});
}
describe.skip = origDescribe.skip;
Differences from the other answers are:
与其他答案的不同之处在于:
- The use of
bind
to call thetests
which ensures that if they call functions onthis
, such asthis.timeout(1000)
will still work. - Handling
.skip
and.only
means that you can still use those on your suite, egdescribe.skip
to temporarily suppress suites. - Replacing the
describe
function by name allows for a less intrusive injection.- This may not be to everyone's taste, in which case obviously an alternative function name can be used whilst still making use of the correct handling of calling the
tests
andonly
andskip
.
- This may not be to everyone's taste, in which case obviously an alternative function name can be used whilst still making use of the correct handling of calling the
- 使用
bind
to calltests
确保如果他们调用函数 onthis
,例如this.timeout(1000)
仍然可以工作。 - 处理
.skip
和.only
意味着您仍然可以在您的套件中使用它们,例如describe.skip
暂时取消套件。 describe
按名称替换函数可以减少侵入性注入。- 这可能不是每个人的口味,在这种情况下,显然是一个别名功能名称可以同时仍利用的调用正确处理使用
tests
和only
和skip
。
- 这可能不是每个人的口味,在这种情况下,显然是一个别名功能名称可以同时仍利用的调用正确处理使用
回答by Tokenyet
@ya_dimon 's solution is working, but If you want to wrap the callback
function of it
, and pass parameter to it as follow.
@ya_dimon 的解决方案是有效的,但如果你想包装 的callback
功能it
,并按如下方式将参数传递给它。
function dynamicTestCase(a) {
return function(done){ console.log(a); } // a is undefined
}
describe("test", function(){
before(function(){
a = 8;
});
it('POST /verifications receiveCode', dynamicTestCase(a)); // a is undefined
})
Why a
is undefined? Because it
is executed before before
in describe
. In this case, @ya_dimon 's solution could not work, but you could make It done trickly as following.
为什么a
是未定义的?因为it
是在before
in之前执行的describe
。在这种情况下,@ya_dimon 的解决方案不起作用,但您可以按照以下方式巧妙地完成它。
function dynamicTestCase(a) {
return function(done){ console.log(a()); } // a is delayed pass! a = 8, remember change a to a()
}
describe("test", function(){
before(function(){
a = 8;
});
it('POST /verifications receiveCode', dynamicTestCase(() => a)); // a is delayed pass!
})
Hope this help to figure out the execution sequence.
希望这有助于找出执行顺序。