Javascript Jest等价于RSpec惰性评估变量(let)?
在rspec中,您可以执行以下操作:Javascript Jest等价于RSpec惰性评估变量(let)?,javascript,testing,ecmascript-6,jestjs,Javascript,Testing,Ecmascript 6,Jestjs,在rspec中,您可以执行以下操作: let(:input) { 'foo' } before_each do setup_some_thing(input) end context 'when input is bar do let(:input) { 'bar' } it 'does something different' do end end context 'when input is baz do let(:input) { 'baz' } it 'do
let(:input) { 'foo' }
before_each do
setup_some_thing(input)
end
context 'when input is bar do
let(:input) { 'bar' }
it 'does something different' do
end
end
context 'when input is baz do
let(:input) { 'baz' }
it 'does something else different' do
end
end
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
beforeAll(() => {
input = 'bar';
});
it('does something different', () => {
});
});
describe('when input is baz', () => {
beforeAll(() => {
input = 'baz';
});
it('does something different', () => {
});
});
});
这允许您将大型对象的方法调用或实例化定义为其较小部分的总和。然后可以在不同的上下文中覆盖这些单独的小部分。其思想是在每次测试之前创建一条快乐路径,然后在上下文块中指定与快乐路径的偏差
不幸的是,我似乎不能开玩笑。我尝试了以下方法:
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
input = 'bar';
it('does something different', () => {
});
});
describe('when input is baz', () => {
input = 'baz';
it('does something different', () => {
});
});
});
因为jest在运行任何特定的描述块之前执行每个描述块,所以输入总是“baz”。有人知道一种变通方法,或者一种获得rspec行为的方法吗
提前谢谢
更新
使用beforeAll可以获得类似的行为(尽管没有延迟评估)
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
beforeAll(() => {
input = 'bar';
});
it('does something different', () => {
});
});
describe('when input is baz', () => {
beforeAll(() => {
input = 'baz';
});
it('does something different', () => {
});
});
});
我发现最好的解决方案是像这样的库 及 如果不想引入依赖项,可以通过如下操作获得类似的行为(尽管没有延迟计算):
let(:input) { 'foo' }
before_each do
setup_some_thing(input)
end
context 'when input is bar do
let(:input) { 'bar' }
it 'does something different' do
end
end
context 'when input is baz do
let(:input) { 'baz' }
it 'does something else different' do
end
end
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
beforeAll(() => {
input = 'bar';
});
it('does something different', () => {
});
});
describe('when input is baz', () => {
beforeAll(() => {
input = 'baz';
});
it('does something different', () => {
});
});
});
我最近创建了自己的库,类似于这里提到的其他库,以实现这个确切的目的,因为我觉得这里提到的其他两个库都有一些缺点。看看 这与Rspec之间的唯一区别在于它实际上并没有将变量放在作用域上,而是让您在给定的函数上访问它(这就是为什么我不想使用bdd-lazy-var) 与given2相比,该库的优势在于它完全支持在给定测试的每次调用之前和之后进行缓存。如果您必须与beforeEach块中的延迟声明变量交互以进行一些设置,则该设置将在实际测试中保留,并在为下一次测试清除之前保留beforeEach块后的设置。使用
beforeEach
在父beforeEach
中设置变量。
基于@Noah自己的答案,我想我也会使用这个来分享我们的最终解决方案
description(“登录”),()=>{
beforeach(()=>login(this.password));//所有步骤都相同,因此重复使用,但使用不同的密码。
描述(“当密码不正确时”,()=>{
在此之前(()=>this.password=“不正确的密码”);
它(“不登录。”,()=>{
//您的断言。
} );
} );
描述(“密码正确时”,()=>{
在此之前(()=>this.password=“CORRECT password”);
它(“成功登录。”,()=>{
//您的断言。
} );
} );
} );
将赋值放在它里面
?或者使用一个不可变的结构(隐式或显式)传递到测试中,而不是依赖,让
也看看我已经有一段时间没有处理过了。关键是代码复制。使用rspec let,您可以避免在每个“it”块中调用setupSomeThing。或在每个描述块中分开前块。对于一个函数,如果没有rspec样式的let,它就有点微不足道了。但是,如果设置需要8种不同的输入,其中一些需要在上下文之间更改,而另一些则不需要,那么在使用“let”变量的before块中只使用一次设置代码就容易多了,这些变量会根据上下文的不同而改变。它最终会彻底清理测试代码。让
s充当声明性控制开关,以命中被测代码的不同分支。这就减少了测试,以清除指定开关是什么的块(本质上是指定要通过的逻辑分支),然后是一组it
块,描述了给定该组let
s应该发生的所有事情。我最大的烦恼是丢失了有助于自动完成的变量类型。您可以添加js文档来帮助提供文档化的键入,这可能会对您有所帮助。ie/**@type{string}*/
不幸的是,这可能不适用于复杂类型,例如泛型:(