I have a Jasmine unit test and in it I have this 'expect'...
expect(mockService.create).toHaveBeenCalledWith(new ToDoItem('a#b.com', 'get milk'));
In my controller I have the following...
todoService.create($scope.newToDo,
function() {
}, function() {
});
But I always get an error because of the final two functions that I pass the service for success and failure. How can I stop this from happening? How do I add them to the expect clause?
Thanks
You may be able to use jasmine.any(Function), or jasmine.objectContaining.
Fair warning, I've never done this myself. However, from the documentation, at least one of them should provide the behaviour you want.
Related
My issue is that I'd like to have a timeout on the expect assertion from Cypress's library but can't seem to figure out a method to do so.
I've tried greatly increasing the global timeout in cypress.conf; however, that didn't work.
if ($widget.find('report-widget')) {
SVGCount++;
expect(barGraphsChange[index]).to.not.equal(undefined)
console.log(barGraphsChange, index)
cy.getBarGraphTotal(SVGCount, barGraphsChange[index])
}
If not a timeout then a reasonable workaround would be nice as well, Thanks!
Also a note: barGraphsChange[index] is in the process of getting calculated and assigned from a called custom Cypress command earlier on during this phase.
You can customise your expectations with should(), and this will automatically retry your assertions for either the specified timeout, or the global defaultCommandTimeout if none provided.
In your case I could probably imagine wrapping your object, specify a timeout and then passing your logic to should:
cy.wrap(someFunction, {timeout: 25000}).should(someFunction => expect(someFunction()).to.eq(someValue))
Read more here: https://docs.cypress.io/api/commands/should.html#Function
Is it possible to call $httpbackend.flush(); only if there are some pending request ?
So I will never get
Error: Unflushed requests: 1,2,3,...,n
Or
Error: No pending request to flush !
According to the documentation there's an $http.pendingRequests property you could use. Something like this would work:
if($http.pendingRequests.length > 0) {
$httpBackend.flush();
}
I'm not sure it s a terribly good idea, but that should do it.
I think You should organize your tests to not use any "if" inside test.
Why?
To keep it simple and easy to understand what is actually tested, "if" gives a way to pass test while it should fail.
Write separate test function to test case when no request are made to API.
Read about AAA (Arrange Act Assert) pattern in testing it will helps you.
If you do not "expect" any requests you could put the call to http.flush(n) in a try-catch block in ignore the exception.
http.whenGet(/* .. */).respond(/*..*/); // maybe implementation needs some data
service.doSomething();
try { http.flush(99); } // resolve all the possible requests my service might have to do
catch(e) {}
expect(service.isAwesome).toBe(true);
Is there a way to get QUnit.js to not run the remaining tests after a single one fails?
Using the following code as an example:
QUnit.test('test1', function(assert) {
assert.equal(1,1);
assert.equal(1,2);
assert.equal(3,3);
});
QUnit.test('test2', function(assert) {
assert.equal(4,4);
assert.equal(5,5);
assert.equal(6,6);
});
Is there some way to get QUnit to stop executing after the assert.equal(1,2)? This means that test2 should never be run.
The best way to stop QUnit after test case fail will be
QUnit.testDone( function( details ) {
if (details.failed>0){
QUnit.config.queue.length = 0;
}
});
Okay, based on my comments above I ran the code below and things to stop as I think you want them to. Again, as I said in the comments, I would really investigate whether this is a good idea. Generally you want your tests to be idempotent such that any one failure does not affect any other test.
Note that we have to set the reorder config option to false here, otherwise QUnit will attempt to run the previously failed test first to "short circuit" things, but you don't want that I'm guessing. I also added a "test0" just to see the fill effect.
QUnit.config.reorder = false;
// This is how we detect the failure and cancel the rest of the tests...
QUnit.testDone(function(details) {
console.log(details);
if (details.name === 'test1' && details.failed) {
throw new Error('Cannot proceed because of failure in test1!');
}
});
QUnit.test('test0', function(assert) {
assert.equal(1,1);
assert.equal(2,2);
assert.equal(3,3);
});
QUnit.test('test1', function(assert) {
assert.equal(1,1);
assert.equal(1,2);
assert.equal(3,3);
});
QUnit.test('test2', function(assert) {
assert.equal(4,4);
assert.equal(5,5);
assert.equal(6,6);
});
You won't get any visual feedback that the tests were canceled because this isn't really interacting with the QUnit UI. However, because we threw an Error object you can open the developer console and see the output there:
I recently read about the solution for these protractor issues:
Unable to easily pass context to addMockModule #695
feat(addMockModule): add third parameter to pass context #787
I have been eager to DRY up my protractor tests and this was the solution I needed. This solution is working great with ChromeDriver, but with FirefoxDriver it's oddly broken. Here's my code (in a beforeEach() block:
var httpBackendMock = function() {
angular.module('httpBackendMock', ['ngMockE2E'])
.value('mockData', arguments[0])
.run(function ($httpBackend, mockData) {
$httpBackend.whenGET(/.*aggregates/)
.respond(200, mockData.testAggregates);
$httpBackend.whenGET(/.*merchants\/123456/)
.respond(200, mockData.testMerchant);
});
};
browser.addMockModule('httpBackendMock', httpBackendMock, {
testAggregates: testAggregates,
testMerchant: testMerchant
});
(testAggregates and testMerchant are defined previously.)
This works perfectly in Chrome, but in Firefox when the whenGET expectations fire they return no data. It fails whether I use the mockData object or directly use arguments[0].
But it gets weirder. If I try to inspect the mockData module value I created above in a later browser.executeScript() call, the data is there, and console.log renders it the same way in both Chrome and Firefox.
browser.get('index.html#/experiments');
browser.executeScript(function() {
return angular.injector(["httpBackendMock"]).get('mockData');
}).then(function(data) {
console.log("DATA", data);
});
When the test runs the data shows up as expected.
The only workaround for this I have found is to JSON.stringify() the input to addMockModule() and JSON.parse() it inside. It seems to work, but is ugly - the framework should already be taking care of it.
So I think this is a bug, but I'm really not sure which component this is a bug in.
Update: I figured out what the issue was, see my comment below.
Is there a way to guarantee state before each Jasmine test?
For example:
describe('some thing', function () {
beforeEach(function () {
doSetup();
// this expect does not evaluate :(
expect(something).toBe(inSomeState);
});
it('has some behavior', function () {
// test code
});
});
The expect inside of the setup make no difference at all. Even throwing an error in the beforeEach does nothing. I would like to have some assurance that the setup has completed correctly before running the next test.. is there a way to do this?
Okay I see what the issue is. Hoping this will help other people out there having this same issue. grunt-contrib-jasmine does not display errors or failed expects inside of beforeEach or afterEach with the display option set to short. Setting this option to full will once again display Errors and failed expects.