Should I write unit-tests for 'wrapper' methods - javascript

I have function in controller of my directive:
$scope.getPossibleWin = function() {
return betslipService.getPossibleWin()
}
betslipService injected into controller
Now I'm thinking how to test $scope.getPossibleWin:
Test that $scope.getPossibleWin calls betslipService.getPossibleWin
Test that $scope.getPossibleWin return correct value (but this already tested in betslipService!)
Test that $scope.getPossibleWin simply exist
What is best practices in wrappers testing?

Option 2 is the best, option 1 I am not very convinced about. I don't have experience with Javascript so I'm not sure why you should have to verify that a function exists (option 3).
You can find more information on it here but the reason that you should indeed add a test for this method is to prevent yourself from breaking anything in the future. If you only rely on that one method 5 layers deep in your application, it could be that one day you add code in a higher layer which changes the result but it is not being tested. Or at some level some code has a side-effect which disturbs the result that came from the bowels of your codebase.
Therefore I would suggest you to make a test for each (relevant) level. The question what should I test exactly is probably a little bit preference-oriented but I would argue that the very least you should do is testing whether it returns the correct value, as layed out above.
Should you test that it calls that specific inner method? You could, but that isn't exactly something you do in unit-testing because then you would be testing against the unit's internal workings. You don't care how it works inside, you just care that the function gives you the response that you expected. By coupling these two in your unit-test, you'll end up with a broken test for non-broken code when you decide to refactor the internal workings.

Related

Should we prefer Chai's `to.be.an('undefined')` vs `to.equal(undefined)`?

Regrettably there is more than one way to do things in Chai.
Is there a benefit either way, to using to.be.an('undefined') over to.equal(undefined)?
My intuition there would be a cost to reusing/recreating undefined. Our test runner gives times for individual tests and it seems like what matters more which runs first (on a test watch the second one is faster, but doing two separate runs means they both take ~2 seconds (full set up) ).
I don't think it really matters. The closest I manage to find to an answer was this article
In that sense, code the expectation in a human-like language, declarative BDD style using expect or should and not using custom code.
The author doesn't seem to draw a distinction between the two and even your testing says they're more-or-less equal.
I say go with whatever makes sense.
Edit:
Based on this stack overflow answer
The more deep is a property nested, more time will be required to perform the property lookup.
That would imply that to.be.an('undefined') would actually be slower than to.equal(undefined) due to the additional lookup, but IMO the prototype pollution that comes with it could give false positives.
Same conclusion as before really: go with what makes sense.

BeforeAll vs. BeforeEach. When to use them?

I was recently looking over a co-workers code and I realized that he implements a jest function in a BeforeAll function at the top of the describe call, and then creates a data object in a beforeEach function. This made me wonder, what exactly are the differences between BeforeAll and BeforeEach.
It was time... I went to Google!! I did find some articles that helped shed some light on some of the functionality differences between the two.
Findings 1: http://breazeal.com/blog/jasmineBefore.html
Findings 2: Difference between #Before, #BeforeClass, #BeforeEach and #BeforeAll
Given the articles I found that BeforeAll is called once and only once. While the BeforeEach is called before each individual test. Which was great! I now had a better idea of when it was being called!
I also found out that the BeforeAll is best used for initializing code. Which makes perfect sense! Initialize it once. Boom, you're done.
My confusion I am having is when is something initialized and when is it not? I have found that BeforeEach in our code is used more often than not. What I am curious about is what kind of code is considered to be "initializing" code, vs whatever code should be in the BeforeEach.
An example from our code below:
beforeAll((done) => {
// Mocking method from within Box file
transferBoxPlanSpy = jest.spyOn(Box, 'transferPlanFromBox').mockImplementation(() => Promise.resolve());
// Pulling data from MongoDB
User.findOne({ user_name: 'testsurgeon1' }, (err, user) => {
user.addMGSPermission();
user.save(done);
});
});
beforeEach(() => {
planData2 = {
user_name: 'hello1',
laterality: 'right',
plan_id: 'testplan42',
order_number: '856-hd-02-l',
file_id: '123456sbyuidbefui',
};
});
I hope my question isn't too vague. Thank you for your time!
Edit 1
I would like to point out that this code was not made by myself, but from one of our members on the software team. He puts the object inside of the BeforeEach, and the mocks inside of the BeforeAll.
My confusion is that it seems like all code can be put just into BeforeAll, with a few exceptions.
Both are used to set up whatever conditions are needed for one or more tests.
If you're certain that the tests don't make any changes to those conditions, you can use beforeAll (which will run once).
If the tests do make changes to those conditions, then you would need to use beforeEach, which will run before every test, so it can reset the conditions for the next one.
Unless the initialization is slow or computationally expensive, it may be safest to default to using beforeEach as it reduces the opportunity for human error, i.e. not realizing that one test is changing the setup for the next one.
The sample you showed is a good example of using both in combination -- the slow network call is put in beforeAll, so it only has to happen once; and the data object (which is presumably modified by the tests) is reset each time in beforeEach.
I know this is an old post but in the event that others come looking I would like to add some important information that I find surprised not to be mentioned here:
That beforeAll is specifically for ASYNCHRONOUS calls that need to complete before the tests are run.
In the original post the beforeAll function is redundant as it doesn't return a promise - you could simply place the function body immediately before your first describe or test
See the jest docs: https://jestjs.io/docs/setup-teardown
In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides beforeAll and afterAll to handle this situation.
E.g. the following returns a promise which will resolve before the tests proceed to run.
beforeAll(() => {
return initializeCityDatabase();
});

How to/ best way to run a test for each element found? Protractor/Jasmine

I am using Protractor and Jasmine.
I'm automating a website that is heavily data-driven with a lot of dynamic elements (elements displayed depend on data available). As a result, I never know exactly how many elements there are, but I need to test each one since data-driven means that just because one works, doesn't mean the rest will.
I'm not sure the best way to go about this - I've done tons of research, but none of the ideas work, or only partially work.
What I've tried:
Throwing an it block into a loop that dynamically grabs the element count
I found that this doesn't work because it appears Jasmine evaluates which / how many tests run at compile. And since I need get to the page before I can grab the count, the count is always 0, so it runs the test 0 times
This only works with static data, but again, my data is dynamic, so this won't work. At least, I couldn't find a way to
Throwing an it block into a loop that loops using a variable and then reassigning the variable in a beforeAll
Same issue as the previous, reassigning doesn't work because Jasmine uses the value that was available on compile
Looping through the elements inside of an 'it' and doing an 'expect' for each element
This works for the most part, but only the first error gets reported. I'd ideally like to see every element that has an issue. Jasmine loops through all elements even when one expect fails, so I'm not sure why it doesn't report them all / or how to report them all
I'd prefer to use solution #3 if I can see all expect failures, but I'm open to any suggestions. If there's a better way, best practice, or a way you handle this instead of what I have listed, I'd like to hear those as well.
Let me know if any more information is needed.

Is it acceptable to execute functions with undefined variables in javascript?

I have a ajax form that populates select lists with values based on the previous selected select list item. This form is used in 3 different views with each view adding an extra select list. I have written some basic validation code that keeps the form process in sync and doesn't confuse the user.
I have written one function that handles all 3 forms in an external script file.
My Question:
Is it acceptable or is there anything I need to worry about if some of my variables are undefined based on the form and view?
Here is some sample code that illustrates my question:
Note: These are not the actual names of my variables.
(function ($){
var objects = {sl1:$('#SelectList1'),sl2:$('#SelectList2'),sl3:$('#SelectList3'),lbl1:$('#Label1'),lbl2:$('#Label2'),lbl3:$('#Label3')};
objects.sl1.change(function(){
mapValues();
}
function mapValues(){
objects.lbl1.text(objects.sl1.val());
objects.lbl2.text(objects.sl2.val());
objects.lbl3.text(objects.sl3.val());//What if this select list is undefined for View1?
}
})(jQuery);
To summarize, View #1 has SelectList1 & SelectList2. View #2 has all 3. Is there a performance issue or is it bad practice to call a function where some of the variables are undefined?
Thanks.
This is more of a jQuery issue, not a JS one. jQuery simply does nothing (it does not even fail!) if you execute a method such as .text() or .val() on an empty result from a selector. For the performance issue, test it yourself. If the element is not found, I expect the performance to be a little better compared to when an element exists.
So, it's valid to use such code.
Note that you're mixing up "undefined variables" with "non-available elements" which are totally different matters. Using undefined variables is strongly discouraged and often lead to unexpected behavior.
I think it's more about readability and maintainability at this point. I mean would it be clear to another developer just by looking at your JS that View #1 has SelectList1 & SelectList2 ? Looking at the code you would think it has all three since all the forms use the same JS. Maybe making it more flexible to where individual forms can specify which selectLists are contained within the respective form, this way the global script is only using the selectLists specified in the forms and not assuming all at available.
Yes it is bad practice. And is source of bugs.
For good practice, define default value, and/or check for it in your function.
thats why you should use the || operator
e.g. :
( $('#SelectList1').length || '0')
The issue is that you will introduce a level of uncertainty, and hence hard to trace bugs, if you do so. Different JS parsers will respond differently - some are more forgiving and will do nothing, others will just crash. So right away you have potential cross-browser issues.
Further, as those variables get passed around inside your code, if you do not know their values, you'll have a difficult time predicting how the rest of your code will interact with them. So now you also have potential logic/program bugs.
So do yourself a favor and a) check that any required parameters are passed, and do some error handling if it is not and b) make sure optional parameters are handled as soon as you receive them (eg assign them a default value, make sure they don't get passed on to other functions if they are not defined, whatever is most appropriate for your application logic).

Test sorting with Cucumber and Capybara

Is there a way to test sorting of a list with Cucumber and Capybara. The sorting is done client-side with javascript.
I was thinking something along the lines of:
Then I should see "first element" and then I should see "second element"
Unfortunately I have no idea how to approach building the steps.
Thanks for the help!
It's a good idea to separate out the stories that you're testing (which you want to get close to plain English) and the actual implementation of the testing (which is hidden in the step_definitions).
There are a few ways to tackle this, depending on what you want to test. In the first case, the cuke test is very readable, and it boils down to implementing the step definitions correctly:
Given that I am on page xyz
And I have a list
Then I should see the list in sorted order
In this case, you'll have to define what it means to have a list (can assign it to #list in a step def if you want), and then what it means to see the list in sorted order (here you can pass a regex that ensures you see item 1 before item 2, etc.)
Alternatively, if you like being more verbose in the cuke tests, you can do something like like:
Given that I am on page xyz
Then I should see /item1.*item2.*item3/
which assumes the list is already populated.
Depending on where the list is, you may have to use a within scope param.
Remember that cucumber is great for functional and integration testing, but probably isn't the right tool for unit testing the sort (looking at all edge cases). To test the sorting at a unit test level, I'd highly recommend using QUnit. Since QUnit tests are static pages, try this trick for running the tests as part of capybara:
Given I am on "/test/path/to/qunit/tests"
Then I should see "Whatever Title You have Assigned"
And I should see "0" within "//p[#id='qunit-testresult']/span/[#class='failed']"

Categories

Resources