Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Test Driven Development with Jasmine and Angular

Test Driven Development with Jasmine and Angular

Description of TDD workflow on an Angular codebase using Jasmine.

Tyson Gern

October 06, 2015
Tweet

More Decks by Tyson Gern

Other Decks in Programming

Transcript

  1. INTRODUCTION So ware Engineer at Pivotal Labs 100% TDD and

    Pair Programming We're new in town We're hiring! ( ) pivotaldublin.com
  2. GOALS You should be testing your javascript. TDD results in

    clean, maintainable code. Jasmine + AngularJS is a great way to start!
  3. TOOLS runs javascript tests on the command line Integrates with

    popular task runners g u l p — g r u n t — Yeoman generators g u l p — g r u n t — karma-jasmine gulp-karma grunt-karma generator-gulp-angular generator-angular
  4. WHAT IS TDD? According to Kent Beck... 1. Don't write

    a line of new code unless you first have a failing automated test. 2. Eliminate duplication.
  5. WHY PRACTICE TDD? Documents behavior of code Easy for new

    developers to join project Stays up to date, unlike comments / / a d d s o n e t o t h e p a s s e d i n v a l u e f u n c t i o n i n c r e m e n t ( n u m b e r ) { r e t u r n n u m b e r + 2 ; }
  6. WHY PRACTICE TDD? Leads to simple design Tests are first

    client of code Solution uses minimal amount of code
  7. EXAMPLE Function a d d S t r i n

    g s that adds integers passed as strings.
  8. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { } ) ;
  9. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { } ) ; } ) ;
  10. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; } ) ; } ) ;
  11. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ;
  12. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; R e f e r e n c e E r r o r : a d d S t r i n g s i s n o t d e f i n e d
  13. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( ) { }
  14. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( ) { } E x p e c t e d u n d e f i n e d t o e q u a l 8 .
  15. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( ) { r e t u r n 8 ; }
  16. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( ) { r e t u r n 8 ; } E x p e c t e d 8 t o e q u a l 1 0 .
  17. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; }
  18. MAKE IT PASS d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { i t ( ' c o r r e c t l y a d d s t w o n u m b e r s ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' 3 ' , ' 5 ' ) ) . t o E q u a l ( 8 ) ; e x p e c t ( a d d S t r i n g s ( ' 4 ' , ' 6 ' ) ) . t o E q u a l ( 1 0 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; }
  19. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; }
  20. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; }
  21. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; }
  22. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { r e t u r n p a r s e I n t ( f i r s t ) + p a r s e I n t ( s e c o n d ) ; } E x p e c t e d N a N t o e q u a l 6 .
  23. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { v a r f i r s t N u m b e r = p a r s e I n t ( f i r s t ) ; i f ( i s N a N ( f i r s t N u m b e r ) ) { f i r s t N u m b e r = 0 ; } r e t u r n f i r s t N u m b e r + p a r s e I n t ( s e c o n d ) ; }
  24. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { v a r f i r s t N u m b e r = p a r s e I n t ( f i r s t ) ; i f ( i s N a N ( f i r s t N u m b e r ) ) { f i r s t N u m b e r = 0 ; } r e t u r n f i r s t N u m b e r + p a r s e I n t ( s e c o n d ) ; } E x p e c t e d N a N t o e q u a l 2 .
  25. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { v a r f i r s t N u m b e r = p a r s e I n t ( f i r s t ) ; i f ( i s N a N ( f i r s t N u m b e r ) ) { f i r s t N u m b e r = 0 ; } v a r s e c o n d N u m b e r = p a r s e I n t ( s e c o n d ) ; i f ( i s N a N ( s e c o n d N u m b e r ) ) { s e c o n d N u m b e r = 0 ; } r e t u r n f i r s t N u m b e r + s e c o n d N u m b e r ; }
  26. ADD A TEST d e s c r i b

    e ( ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { v a r f i r s t N u m b e r = p a r s e I n t ( f i r s t ) ; i f ( i s N a N ( f i r s t N u m b e r ) ) { f i r s t N u m b e r = 0 ; } v a r s e c o n d N u m b e r = p a r s e I n t ( s e c o n d ) ; i f ( i s N a N ( s e c o n d N u m b e r ) ) { s e c o n d N u m b e r = 0 ; } r e t u r n f i r s t N u m b e r + s e c o n d N u m b e r ; }
  27. REFACTOR d e s c r i b e (

    ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { v a r f i r s t N u m b e r = p a r s e I n t ( f i r s t ) ; i f ( i s N a N ( f i r s t N u m b e r ) ) { f i r s t N u m b e r = 0 ; } v a r s e c o n d N u m b e r = p a r s e I n t ( s e c o n d ) ; i f ( i s N a N ( s e c o n d N u m b e r ) ) { s e c o n d N u m b e r = 0 ; } r e t u r n f i r s t N u m b e r + s e c o n d N u m b e r ; }
  28. REFACTOR d e s c r i b e (

    ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { f u n c t i o n p a r s e N u m b e r ( s t r i n g ) { v a r n u m b e r = p a r s e I n t ( s t r i n g ) ; r e t u r n i s N a N ( n u m b e r ) ? 0 : n u m b e r ; } r e t u r n p a r s e N u m b e r ( f i r s t ) + p a r s e N u m b e r ( s e c o n d ) ; }
  29. REFACTOR d e s c r i b e (

    ' a d d S t r i n g s ' , f u n c t i o n ( ) { / / . . . i t ( ' t r e a t s n o n - n u m b e r s a s 0 ' , f u n c t i o n ( ) { e x p e c t ( a d d S t r i n g s ( ' a ' , ' 6 ' ) ) . t o E q u a l ( 6 ) ; e x p e c t ( a d d S t r i n g s ( ' 2 ' , ' ' ) ) . t o E q u a l ( 2 ) ; } ) ; } ) ; f u n c t i o n a d d S t r i n g s ( f i r s t , s e c o n d ) { f u n c t i o n p a r s e N u m b e r ( s t r i n g ) { v a r n u m b e r = p a r s e I n t ( s t r i n g ) ; r e t u r n i s N a N ( n u m b e r ) ? 0 : n u m b e r ; } r e t u r n p a r s e N u m b e r ( f i r s t ) + p a r s e N u m b e r ( s e c o n d ) ; }
  30. 2-WAY BINDING WITH $ S C O P E Angular

    synchronizes controllers and views with $ s c o p e . < d i v n g - c o n t r o l l e r = " m e s s a g i n g . f l a s h C o n t r o l l e r " > < h 3 > { { m e s s a g e } } < / h 3 > < / d i v > + a n g u l a r . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e ) { $ s c o p e . m e s s a g e = ' h e l l o ' ; } ) ; = < d i v n g - c o n t r o l l e r = " m e s s a g i n g . f l a s h C o n t r o l l e r " > < h 3 > h e l l o < / h 3 > < / d i v >
  31. DEPENDENCY INJECTION Angular uses dependency injection to provide objects with

    collaborators. a n g u l a r . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { } ) ;
  32. MODULES Modules allow building application with modules. a n g

    u l a r . m o d u l e ( ' u s e r s ' , [ ] ) ; / / g r e e t e r A p p l i c a t i o n a n g u l a r . m o d u l e ( ' t w i t t e r A d a p t e r ' , [ ] ) ; / / / \ a n g u l a r . m o d u l e ( ' m e s s a g i n g ' , [ / / / \ ' t w i t t e r A d a p t e r ' / / / \ ] ) ; / / m e s s a g i n g u s e r s / / | a n g u l a r . m o d u l e ( ' g r e e t e r A p p l i c a t i o n ' , [ / / | ' u s e r s ' , / / | ' m e s s a g i n g ' / / t w i t t e r A d a p t e r ] ) ; / /
  33. EXAMPLE! Start to build g r e e t e

    r A p p l i c a t i o n
  34. FEATURE Show initial greeting when the page loads < d

    i v n g - a p p = " g r e e t e r A p p l i c a t i o n " > < d i v n g - c o n t r o l l e r = " m e s s a g i n g . f l a s h C o n t r o l l e r " > < h 3 > { { m e s s a g e } } < / h 3 > < / d i v > < / d i v >
  35. TEST SETUP d e s c r i b e

    ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { b e f o r e E a c h ( m o d u l e ( ' m e s s a g i n g ' ) ) ; / / t e s t s g o h e r e } ) ;
  36. TEST SETUP d e s c r i b e

    ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e ; b e f o r e E a c h ( m o d u l e ( ' m e s s a g i n g ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( $ r o o t S c o p e ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  37. TEST SETUP d e s c r i b e

    ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e ; b e f o r e E a c h ( m o d u l e ( ' m e s s a g i n g ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( $ r o o t S c o p e , $ c o n t r o l l e r ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; $ c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , { $ s c o p e : $ s c o p e } ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  38. TEST SETUP d e s c r i b e

    ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e , m e s s a g i n g S e r v i c e ; b e f o r e E a c h ( m o d u l e ( ' m e s s a g i n g ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( . . . , _ m e s s a g i n g S e r v i c e _ ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; m e s s a g i n g S e r v i c e = _ m e s s a g i n g S e r v i c e _ ; s p y O n ( m e s s a g i n g S e r v i c e , ' g e t M e s s a g e ' ) . a n d . r e t u r n V a l u e ( ' H i ! ' ) ; $ c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , { $ s c o p e : $ s c o p e , m e s s a g i n g S e r v i c e : m e s s a g i n g S e r v i c e } ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  39. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / s e t u p d e s c r i b e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e m e s s a g e ' , f u n c t i o n ( ) { } ) ; } ) ; } ) ;
  40. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / s e t u p d e s c r i b e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e m e s s a g e ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; } ) ; } ) ; } ) ;
  41. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / s e t u p d e s c r i b e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e m e s s a g e ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' i n i t i a l ' ) ; } ) ; } ) ; } ) ;
  42. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / s e t u p d e s c r i b e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e m e s s a g e ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' i n i t i a l ' ) ; } ) ; } ) ; } ) ; E x p e c t e d u n d e f i n e d t o e q u a l ' H i ! ' .
  43. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / s e t u p d e s c r i b e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e m e s s a g e ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' i n i t i a l ' ) ; } ) ; } ) ; } ) ; E x p e c t e d s p y g e t M e s s a g e t o h a v e b e e n c a l l e d w i t h [ ' i n i t i a l ' ] b u t i t w a s n e v e r c a l l e d .
  44. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { } ) ;
  45. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; } ) ;
  46. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; } ) ;
  47. REFACTOR? a n g u l a r . m

    o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; } ) ;
  48. REFACTOR? a n g u l a r . m

    o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; } ) ;
  49. FEATURE Change the message to prompt the user a er

    5 seconds < d i v n g - a p p = " g r e e t e r A p p l i c a t i o n " > < d i v n g - c o n t r o l l e r = " m e s s a g i n g . f l a s h C o n t r o l l e r " > < h 3 > { { m e s s a g e } } < / h 3 > < / d i v > < / d i v >
  50. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / t e s t s a n d s e t u p d e s c r i b e ( ' a f t e r w a i t i n g 5 s e c o n d s ' , f u n c t i o n ( ) { i t ( ' s h o w s t h e \ ' p r o m p t \ ' m e s s a g e ' , f u n c t i o n ( ) { } ) ; } ) ; } ) ;
  51. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / t e s t s a n d s e t u p d e s c r i b e ( ' a f t e r w a i t i n g 5 s e c o n d s ' , f u n c t i o n ( ) { i t ( ' s h o w s t h e \ ' p r o m p t \ ' m e s s a g e ' , f u n c t i o n ( ) { $ s c o p e . m e s s a g e = ' ' ; $ t i m e o u t . f l u s h ( 4 9 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' ' ) ; } ) ; } ) ; } ) ;
  52. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / t e s t s a n d s e t u p d e s c r i b e ( ' a f t e r w a i t i n g 5 s e c o n d s ' , f u n c t i o n ( ) { i t ( ' s h o w s t h e \ ' p r o m p t \ ' m e s s a g e ' , f u n c t i o n ( ) { $ s c o p e . m e s s a g e = ' ' ; $ t i m e o u t . f l u s h ( 4 9 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' ' ) ; $ t i m e o u t . f l u s h ( 2 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' p r o m p t ' ) ; } ) ; } ) ; } ) ;
  53. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / t e s t s a n d s e t u p d e s c r i b e ( ' a f t e r w a i t i n g 5 s e c o n d s ' , f u n c t i o n ( ) { i t ( ' s h o w s t h e \ ' p r o m p t \ ' m e s s a g e ' , f u n c t i o n ( ) { $ s c o p e . m e s s a g e = ' ' ; $ t i m e o u t . f l u s h ( 4 9 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' ' ) ; $ t i m e o u t . f l u s h ( 2 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' p r o m p t ' ) ; } ) ; } ) ; } ) ; E x p e c t e d ' ' t o e q u a l ' H i ! ' .
  54. ADD A TEST d e s c r i b

    e ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( ) { / / t e s t s a n d s e t u p d e s c r i b e ( ' a f t e r w a i t i n g 5 s e c o n d s ' , f u n c t i o n ( ) { i t ( ' s h o w s t h e \ ' p r o m p t \ ' m e s s a g e ' , f u n c t i o n ( ) { $ s c o p e . m e s s a g e = ' ' ; $ t i m e o u t . f l u s h ( 4 9 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' ' ) ; $ t i m e o u t . f l u s h ( 2 0 0 ) ; e x p e c t ( $ s c o p e . m e s s a g e ) . t o E q u a l ( ' H i ! ' ) ; e x p e c t ( m e s s a g i n g S e r v i c e . g e t M e s s a g e ) . t o H a v e B e e n C a l l e d W i t h ( ' p r o m p t ' ) ; } ) ; } ) ; } ) ; E x p e c t e d s p y g e t M e s s a g e t o h a v e b e e n . . .
  55. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; } ) ;
  56. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; $ t i m e o u t ( f u n c t i o n ( ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' p r o m p t ' ) ; } , 5 0 0 0 ) ; } ) ;
  57. MAKE IT PASS! a n g u l a r

    . m o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; $ t i m e o u t ( f u n c t i o n ( ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' p r o m p t ' ) ; } , 5 0 0 0 ) ; } ) ;
  58. REFACTOR? a n g u l a r . m

    o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' i n i t i a l ' ) ; $ t i m e o u t ( f u n c t i o n ( ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( ' p r o m p t ' ) ; } , 5 0 0 0 ) ; } ) ;
  59. REFACTOR! a n g u l a r . m

    o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { f u n c t i o n s e t M e s s a g e ( t y p e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( t y p e ) ; } s e t M e s s a g e ( ' i n i t i a l ' ) ; $ t i m e o u t ( f u n c t i o n ( ) { s e t M e s s a g e ( ' p r o m p t ' ) ; } , 5 0 0 0 ) ; } ) ;
  60. REFACTOR! a n g u l a r . m

    o d u l e ( ' m e s s a g i n g ' ) . c o n t r o l l e r ( ' m e s s a g i n g . f l a s h C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , $ t i m e o u t , m e s s a g i n g S e r v i c e ) { f u n c t i o n s e t M e s s a g e ( t y p e ) { $ s c o p e . m e s s a g e = m e s s a g i n g S e r v i c e . g e t M e s s a g e ( t y p e ) ; } s e t M e s s a g e ( ' i n i t i a l ' ) ; $ t i m e o u t ( f u n c t i o n ( ) { s e t M e s s a g e ( ' p r o m p t ' ) ; } , 5 0 0 0 ) ; } ) ;
  61. FEATURE Show the current user < d i v n

    g - a p p = " g r e e t e r A p p l i c a t i o n " > < d i v n g - c o n t r o l l e r = " u s e r s . c u r r e n t C o n t r o l l e r " > < h 2 > W e l c o m e { { c u r r e n t U s e r } } ! < / h 2 > < / d i v > < d i v n g - c o n t r o l l e r = " m e s s a g i n g . f l a s h C o n t r o l l e r " > < h 3 > { { m e s s a g e } } < / h 3 > < / d i v > < / d i v >
  62. SETUP d e s c r i b e (

    ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e , u s e r s S e r v i c e , d e f e r r e d ; b e f o r e E a c h ( m o d u l e ( ' u s e r s ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( $ r o o t S c o p e , $ c o n t r o l l e r , $ q , _ u s e r s S e r v i c e _ ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; u s e r s S e r v i c e = _ u s e r s S e r v i c e _ ; $ c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , { $ s c o p e : $ s c o p e , u s e r s S e r v i c e : u s e r s S e r v i c e } ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  63. SETUP d e s c r i b e (

    ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e , u s e r s S e r v i c e , d e f e r r e d ; b e f o r e E a c h ( m o d u l e ( ' u s e r s ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( $ r o o t S c o p e , $ c o n t r o l l e r , $ q , _ u s e r s S e r v i c e _ ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; u s e r s S e r v i c e = _ u s e r s S e r v i c e _ ; d e f e r r e d = $ q . d e f e r ( ) ; $ c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , { $ s c o p e : $ s c o p e , u s e r s S e r v i c e : u s e r s S e r v i c e } ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  64. SETUP d e s c r i b e (

    ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( ) { v a r $ s c o p e , u s e r s S e r v i c e , d e f e r r e d ; b e f o r e E a c h ( m o d u l e ( ' u s e r s ' ) ) ; b e f o r e E a c h ( i n j e c t ( f u n c t i o n ( $ r o o t S c o p e , $ c o n t r o l l e r , $ q , _ u s e r s S e r v i c e _ ) { $ s c o p e = $ r o o t S c o p e . $ n e w ( ) ; u s e r s S e r v i c e = _ u s e r s S e r v i c e _ ; d e f e r r e d = $ q . d e f e r ( ) ; s p y O n ( u s e r s S e r v i c e , ' g e t C u r r e n t ' ) . a n d . r e t u r n V a l u e ( d e f e r r e d . p r o m i s e ) ; $ c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , { $ s c o p e : $ s c o p e , u s e r s S e r v i c e : u s e r s S e r v i c e } ) ; } ) ) ; / / t e s t s g o h e r e } ) ;
  65. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { } ) ; } ) ;
  66. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; } ) ; } ) ;
  67. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; d e f e r r e d . r e s o l v e ( ' @ w a l k e n 2 0 ' ) ; } ) ; } ) ;
  68. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; d e f e r r e d . r e s o l v e ( ' @ w a l k e n 2 0 ' ) ; $ s c o p e . $ a p p l y ( ) ; } ) ; } ) ;
  69. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; d e f e r r e d . r e s o l v e ( ' @ w a l k e n 2 0 ' ) ; $ s c o p e . $ a p p l y ( ) ; e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' @ w a l k e n 2 0 ' ) ; } ) ; } ) ;
  70. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; d e f e r r e d . r e s o l v e ( ' @ w a l k e n 2 0 ' ) ; $ s c o p e . $ a p p l y ( ) ; e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' @ w a l k e n 2 0 ' ) ; } ) ; } ) ; E x p e c t e d u n d e f i n e d t o e q u a l ' L o a d i n g ' .
  71. ADD A TEST d e s c r i b

    e ( ' w h e n t h e c o n t r o l l e r l o a d s ' , f u n c t i o n ( ) { i t ( ' s e t s t h e c u r r e n t u s e r ' , f u n c t i o n ( ) { e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' L o a d i n g ' ) ; d e f e r r e d . r e s o l v e ( ' @ w a l k e n 2 0 ' ) ; $ s c o p e . $ a p p l y ( ) ; e x p e c t ( $ s c o p e . c u r r e n t U s e r ) . t o E q u a l ( ' @ w a l k e n 2 0 ' ) ; } ) ; } ) ; E x p e c t e d u n d e f i n e d t o e q u a l ' @ w a l k e n 2 0 ' .
  72. MAKE IT PASS a n g u l a r

    . m o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { } ) ;
  73. MAKE IT PASS a n g u l a r

    . m o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { $ s c o p e . c u r r e n t U s e r = ' L o a d i n g ' ; } ) ;
  74. MAKE IT PASS a n g u l a r

    . m o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { $ s c o p e . c u r r e n t U s e r = ' L o a d i n g ' ; u s e r s S e r v i c e . g e t C u r r e n t ( ) . t h e n ( f u n c t i o n ( r e s u l t ) { $ s c o p e . c u r r e n t U s e r = r e s u l t ; } ) ; } ) ;
  75. MAKE IT PASS a n g u l a r

    . m o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { $ s c o p e . c u r r e n t U s e r = ' L o a d i n g ' ; u s e r s S e r v i c e . g e t C u r r e n t ( ) . t h e n ( f u n c t i o n ( r e s u l t ) { $ s c o p e . c u r r e n t U s e r = r e s u l t ; } ) ; } ) ;
  76. REFACTOR? a n g u l a r . m

    o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { $ s c o p e . c u r r e n t U s e r = ' L o a d i n g ' ; u s e r s S e r v i c e . g e t C u r r e n t ( ) . t h e n ( f u n c t i o n ( r e s u l t ) { $ s c o p e . c u r r e n t U s e r = r e s u l t ; } ) ; } ) ;
  77. REFACTOR! a n g u l a r . m

    o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { f u n c t i o n s e t C u r r e n t U s e r ( u s e r ) { $ s c o p e . c u r r e n t U s e r = u s e r ; } s e t C u r r e n t U s e r ( ' L o a d i n g ' ) ; u s e r s S e r v i c e . g e t C u r r e n t ( ) . t h e n ( s e t C u r r e n t U s e r ) ; } ) ;
  78. REFACTOR! a n g u l a r . m

    o d u l e ( ' u s e r s ' ) . c o n t r o l l e r ( ' u s e r s . c u r r e n t C o n t r o l l e r ' , f u n c t i o n ( $ s c o p e , u s e r s S e r v i c e ) { f u n c t i o n s e t C u r r e n t U s e r ( u s e r ) { $ s c o p e . c u r r e n t U s e r = u s e r ; } s e t C u r r e n t U s e r ( ' L o a d i n g ' ) ; u s e r s S e r v i c e . g e t C u r r e n t ( ) . t h e n ( s e t C u r r e n t U s e r ) ; } ) ;
  79. You should be testing your javascript. TDD results in clean,

    maintainable code. Jasmine + AngularJS is a great way to start!
  80. THANKS! See slides at Run tests from slides See the

    application tygern.github.io/jasmine-tdd here here