Angular testing cheat sheet

Sen verran useasti Angularin parissa tulee pyörittyä, että pidän seinälle tulostettuna muutamaa yleisintä testaukseen liittyvää jippoa. Javascript kun ei anna käännöksenaikaista palautetta, on erityisen tärkeää tietää API. Samoin liikkeellä on myös huonoa ja vanhentunutta tietoa; Yli puolet netin resursseista listailee vanhentuneita komentoja esim. jasminen ja protratorin rajapinnoista.

Pidemmittä puheitta siis, tässä Angular testauksen cheat sheet:

// jasmine matchers
describe('jasmine matchers', function() {
  it('demonstrate use of built-in matchers', function() {
    expect(true).toBeTruthy();
    expect(false).not.toBeTruthy();
    expect(false).toBeFalsy();
    expect(true).not.toBeFalsy();
    expect({}).toBeDefined();
    expect(undefined).not.toBeDefined();
    expect(null).toBeNull();
    expect(undefined).not.toBeNull();
    expect({}).not.toBeNull();
    expect('Hello World!').toEqual('Hello World!');
    expect('Hello World!').not.toEqual('Goodbye!');
    expect('Hello World!').toNotEqual('Hi!');
    expect([1, 2, 3]).toEqual([1, 2, 3]);
    expect(1).toEqual(1);
    expect({ foo: 1 }).toEqual({ foo: 1 });
    expect(1.223).toBeCloseTo(1.22);
    expect(1.233).not.toBeCloseTo(1.22);
    expect(1.23326).toBeCloseTo(1.23324, 3);
    expect([1, 2, 3]).toContain(2);
    expect([1, 2, 3]).not.toContain(4);
    expect('Hello Jasmine').toMatch(/jasmine/i);
    expect('phone: 123-45-67').toMatch(/\d{3}-\d{2}-\d{2}/);
    expect(2).toBeGreaterThan(1);
    expect(2).toBeLessThan(3);
    expect(object.doSomething).toThrow(new Error("Unexpected error!"));
  });
});

// Creating custom matchers
  beforeEach(function() {
    this.addMatchers({
      toBeGET: function() {
        var actual = this.actual.method;
        return actual === 'GET';
      },
      toHaveUrl: function(expected) {
        var actual = this.actual.url;
        this.message = function() {
          return "Expected request to have url " + expected + " but was " + actual
        };
      return actual === expected;
     }
   });
});
// Protractor API: http://angular.github.io/protractor/#/api
// Note: Most commands return promises, so you only resolve their values
 // through using jasmine expect API or using .then(function()) structure

// Control browser
browser.get('yoururl'); // Load address, can also use '#yourpage'
browser.navigate().back();
browser.navigate().forward();
browser.sleep(10000); // if your test is outrunning the browser
browser.waitForAngular(); // if your test is outrunning the browser
browser.getLocationAbsUrl() // get the current address

//Here's a trick how to wait for something to become present/visible:
browser.wait(element(by.id('some-element-id')).isPresent);

// Control buttons
element(by.id('create')).click(); // Click a button or other item

// Check visibility
element(by.id('create')).isPresent(); // Careful with this: element is often present while it's not displayed...
element(by.id('create')).isEnabled(); // enabled/disabled, as in ng-disabled...
element(by.id('create')).isDisplayed(); // Is element currently visible/displayed?

// Find an element by id, model, binding, ...
element(by.id('user_name'));
element(by.css('#myItem'));
element(by.model('person.name')); // refers to ng-model directive
element(by.binding('person.concatName')); // refers to ng-bind directive
element(by.textarea('person.extraDetails'));
element (by.input( 'username' ));
element (by.input( 'username' )).clear();
element(by.buttonText('Save'));
element(by.partialButtonText('Save'));
element(by.linkText('Save'));
element(by.partialLinkText('Save'));
element(by.css('[ng-click="cancel()"]')); 

var dog = element(by.cssContainingText('.pet', 'Dog'));
var allOptions = element.all(by.options('c for c in colors')); // when ng-options is used with selectbox

// Find collection of elements by css, repeater, xpath..
var list = element.all(by.css('.items li'));
var list2 = element.all(by.repeater('person in home.results'));
var list3 = element.all(by.xpath('//div'));
expect(list.count()).toBe(3);
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
expect(list.first().getText()).toBe('First');
expect(list.last().getText()).toBe('Last');

// Send keystrokes, clear
element(by.id('user_name')). sendKeys("user1");
sendKeys(protractor.Key.ENTER);
sendKeys(protractor.Key.TAB);
element(by.id('user_name')).clear();

// Position and size, also how to deal with promises:
element(by.id('item1')).getLocation().then(function(location) {
  var x = location.x;
  var y = location.y;
});
element(by.id('item1')).getSize().then(function(size) {
 var width = size.width;
 var height = size.height;
});
// Jasmine spy / mocks
//How to spy on a method?
spyOn(obj, 'method') // assumes obj.method is a function
//How to verify it was called?
expect(obj.method).toHaveBeenCalled()
//How to verify it was called with specific arguments?
expect(obj.method).toHaveBeenCalledWith('foo', 'bar')

//How many times was it called?
obj.method.callCount

//What were the arguments to the last call?
obj.method.mostRecentCall.args

//How to reset all the calls made to the spy so far?
obj.method.reset()

//How to make a standalone spy function?
var dummy = jasmine.createSpy('dummy')
$('button#mybutton').click(dummy)

//How to have spied method also calls through to the real function?
spyOn(obj, 'method').and.callThrough()

//How do I fix the return value of a spy? spyOn(obj, 'method').and.return('Pow!')

//How to have spied method be replaced by fake implementation?
spyOn(obj, 'method').and.callFake(function() {
  return "HELLO";
});

// Arguments for callFake function are in arguments array, for example 1st argument: arguments[0]
// Prepare a mock
spyOn(configurations, 'getObjectId').and.callFake(function () {
  switch (arguments[0]) {
    case "HEADEROBJECT":
      return 1;
    case "FOOTEROBJECT":
      return 2;
    default:
      return -1;
   }
});

//How to get all arguments for all calls that have been made to the spy?
obj.method.argsForCall // this is an array

// if you want to mock without an object
var myFoo = jasmine.createSpyObj('sender', ['send']);

// Create fake implementation for empty mock
myFoo.send.andCallFake(function() {return ['some', 'fake', 'data'];});

// Same with some parameters
myFoo.send.andCallFake(function(arg1,arg2) {
  return [arg1*2,arg2*3];
});

// To expect any types
expect(this.sender.send).toHaveBeenCalledWith("my message", any(Function), any(Function));
Advertisements

Vastaa

Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:

WordPress.com-logo

Olet kommentoimassa WordPress.com -tilin nimissä. Log Out / Muuta )

Twitter-kuva

Olet kommentoimassa Twitter -tilin nimissä. Log Out / Muuta )

Facebook-kuva

Olet kommentoimassa Facebook -tilin nimissä. Log Out / Muuta )

Google+ photo

Olet kommentoimassa Google+ -tilin nimissä. Log Out / Muuta )

Muodostetaan yhteyttä palveluun %s