Pistos Pistos - 2 months ago 6
Javascript Question

Javascript testing equivalent of Ruby's rspec let

In the Ruby world, using rspec, we have a feature available to us called

let
(https://relishapp.com/rspec/rspec-core/docs/helper-methods/let-and-let). Its primary benefit is that it's lazy evaluated, so we can write tests like this:

describe Thing do
describe "#process" do
let(:arg) { nil }
let(:result) { Thing.new.process(arg) }

context "given 3" do
let(:arg) { 3 }

it "returns 12" do
expect(result).to eq 12
end
end

context "given 7" do
let(:arg) { 7 }

it "returns 42" do
expect(result).to eq 42
end
end
end
end


The point being we don't have to have a line to calculate the
result
inside every single
it
block.

My question is: In the world of Javascript, is there a library or framework which provides an equivalent feature?

I am used to writing with Jasmine, but I'm not married to that, and could use Mocha or something else if it had this lazy evalution feature I'm looking for.

I suspect there's a way to do it with a long-winded convolution of
beforeEach
and
function () {...}
declarations and things like that, but ideally proposed solutions would have a nice, concise and elegant syntax.

I'm aware of jasmine-let, but it is 4 years old, unmaintained, and doesn't look like a popular or official tool. Also, I'm relatively new to more modern Javascript development, so I don't even know where
component install _____
comes from (what tool).

This seems to be a useful blog post if I wanted to roll my own solution: http://blog.gypsydave5.com/2015/03/21/lazy-eval-and-memo/

Oh, and in case it matters, I will mention that I am writing in ES6.

Answer

If you're looking for lazy variable evaluation in a Jasmine unit test, there are a slim few alternatives, but there is a fork made last year to let it work with v2.3+ by a fellow named Warren Ouyang (globetro).

There is also a closed issue on the Mocha Github describing the scenario exactly. Some people have posted examples that match the feature, alternatives, and explicit implementations of the feature that are more like RSpec there. (See here and here.)

describe('Thing', () => {

  def('arg', () => null );

  return describe('process', () => {

    def('process', () => new Thing().process($arg) )

    context('given 3', () => {
      def('arg', () => 3 );
      it('returns 12', () => expect($process).to.equal(12))
    })

    context('given 7', () => {
      def('arg', () => 7)
      it('returns 42', () => expect($process).to.equal(42))
    })

  })

})

Here's the above example on jsfiddle.net. This uses a more terse style of JavaScript.

Here's the previous example of using bdd-lazy-var/rspec on jsfiddle.net.

Edit: See other answer using CoffeeScript for brevity. This answer is JavaScript.

Comments