Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injecting 3rd-party libraries into specs #4

Closed
netaisllc opened this issue Sep 28, 2014 · 7 comments
Closed

Injecting 3rd-party libraries into specs #4

netaisllc opened this issue Sep 28, 2014 · 7 comments
Labels

Comments

@netaisllc
Copy link

Hi, I am experimenting with your project which is very cool. Can you offer any guidance as to how to inject 3rd-party libraries into a spec file.

The use case is this; my module EVENTS is under-test, and it depends on JQUERY and AMPLIFY, both of which are known 3rd party libs that I'm willing to "trust" in regard to unit testing my module. I don't really want to mock them out, as I'm testing EVENTS' use of them.

I can't quite get my head around how to declare them, or maybe I am looking at this the wrong way?

@biril biril added the question label Sep 28, 2014
@biril
Copy link
Owner

biril commented Sep 29, 2014

Hey @netaisllc

you shouldn't need to declare modules that you don't plan to mock. Given that the events module declares jQuery and amplify as dependencies

// In path/to/events/mod.js:
define(['path/to/jQuery', 'path/to/amplify'], function ($, amplify) {
  // ...
})

you can create a suite without having to reference them - you only need to reference the module under test:

// In test/events.spec.js or whatever
describe('The events module', 'path/to/events/mod', function () {
  it('should do something', function (eventsMod, deps) {
    // Expectations go here. Such as
    expect(eventsMod.hasDoneSomething()).toBe(true);

    // _If_ that's useful to you, you can access the (original,
    //  non-mocked) jQuery and amplify as deps.$ and deps.amplify
  }
});

Module dependencies are always reloaded per spec along with the module itself.

Hope that's useful - let me know if you have further questions.

@netaisllc
Copy link
Author

Thanks @biril!

That makes sense, but I still experience reference errors. I am actually using the alternative parameter api for "it" - that is, I am passing in an unnamed object with the properties mock and expect. So my questions are:

  1. I thought the MUT (module under test was automatically injected to each IT in a suite. No? Your example above explicity passes it.
  2. Can you help me understand how to include the deps parameter when using the alt api as I am?

Additionally, I can resolve my errors by (a) including the PATHS object used in the actual app into the TestRunner's RequireJS config, and then (b) declaring the 3rd party libraries in the DEFINE of the spec file.

But that's ugly and headed the wrong way, isn't it?

@biril
Copy link
Owner

biril commented Sep 30, 2014

So, starting from the last part of your question, (a) sounds reasonable. In both the app and the app's test-suite, require needs to do the same lookups - load the same modules. I would expect it to be configured very similarly for both environments (e.g. same paths property, same baseUrl property etc). (b) doesn't sound right though - it should be the MUT loading the 3rd party libraries it depends on. In turn, the MUT - let's assume it's the events module - will be loaded by the test suite due to the line

describe('The events module', 'path/to/events/mod', function () { // ...

which 'ties' the module path/to/events/mod to the suite 'The events module'.

This will indeed make the module available to all it-specs within the suite: It will be passed to every expectation function as the very first parameter. Here's the example from my previous answer, modified for the case of using a specConfig hash in place of an expectation function:

// In test/events.spec.js or whatever
describe('The events module', 'path/to/events/mod', function () {
  it('should do something', {
    // mock is an empty object as no deps are to be mocked - can also be skipped
    mock: {},

    // expect is just the expectation function of the previous example
    expect: function (eventsMod, deps) {
      // Expectations go here. Such as
      expect(eventsMod.hasDoneSomething()).toBe(true);

      // _If_ that's useful to you, you can access the (original,
      //  non-mocked) jQuery and amplify as deps.$ and deps.amplify
    }
  }
});

Was that helpful?

Also, when you say 'experiencing reference errors' do you mean require is failing to locate and load modules? That would point to some requirejs configuration issue rather than a jasq issue. Or is it some other error?

@netaisllc
Copy link
Author

Yes, that's extremely clear and helpful; it works as you describe.

I realize now that part of my problem is in test setup -- ie, an error in my Jasmine fu, and probably not at all relating to Jasq. Really appreciate your guidance; a great project that should get wider mention.... :)

BTW, in your example directly above, what is best practice for the location of a VAR to be used in the actual expectation? By that I mean, imagine a matcher that is

.toEqual(MyVar);

-- my issue is around where to declare MyVar, particularly when MyVar is a property of a 3rd party library, or computed using one ( a date computed using Moment.js, for example). Thoughts?

@biril
Copy link
Owner

biril commented Oct 2, 2014

Well, here's a couple of thoughts (meant as subjective, unscientific opinion, naturally):

If it's a value that needs to be available to a group of specs, I would probably use beforeEach. Particularly if it's not a scalar value, but something more complex - a hash for example. (Note that, unfortunately, the current revision of Jasq doesn't allow access to the module under test, or it's dependencies inside a beforeEach. This is future work.)

Otherwise, I would just declare / compute it per spec.

Generally I would try to keep stuff 'as static as possible' as introducing dynamically generated values - by a 3rd party library - could potentially complicate the code and make the tests harder to follow.

@biril biril closed this as completed Oct 2, 2014
@netaisllc
Copy link
Author

Thanks.
Yeah I get 'static as possible', but one of my tests validates the runtime development of a query parameter that specifies a date range based on @today and @today - days. So dynamically computing the expected results is a real time-saver.
Thanks so much for the opinion and the project!!

@biril
Copy link
Owner

biril commented Oct 3, 2014

Thanks for the feedback @netaisllc! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants