Design Patterns for MVVM Unit Testing & Testability

  • Published on
    23-Feb-2016

  • View
    25

  • Download
    1

Embed Size (px)

DESCRIPTION

Design Patterns for MVVM Unit Testing & Testability. Benjamin Day. Benjamin Day. Consultant, Coach, Trainer Scrum.org Classes Professional Scrum Developer (PSD) Professional Scrum Foundations (PSF) TechEd , VSLive , DevTeach , OReilly OSCON - PowerPoint PPT Presentation

Transcript

<p>Presentation title</p> <p>Design Patterns for MVVM Unit Testing &amp; TestabilityBenjamin Day</p> <p>Benjamin DayConsultant, Coach, TrainerScrum.org ClassesProfessional Scrum Developer (PSD)Professional Scrum Foundations (PSF) TechEd, VSLive, DevTeach, OReilly OSCONVisual Studio Magazine, Redmond Developer NewsMicrosoft MVP for Visual Studio ALMTeam Foundation Server, TDD, Testing Best Practices,Silverlight, Windows Azurehttp://blog.benday.combenday@benday.com</p> <p>AgendaMy assumptionsSuper-fast overview Model-View-ViewModel (MVVM)Unit testingHow to build stuff and test stuff.</p> <p>AssumptionsAutomated tests are required for doneUnit tests are written by developers.QA testing is different from developer testing.</p> <p>MVVM in Silverlight is harder than WPF(My demos will be in Silverlight.)Design for testability? Way of architecting your applicationEasy to write &amp; run automated tests</p> <p>Things that need to be architected.Requirement: design for testability</p> <p>Requirement: testability in isolation They call them unit tests for a reason.Helps to remember Single Responsibility Principle (SRP)</p> <p>In Silverlight, figure out async first.Not planning for async will crush SRP.</p> <p>SOLID Principles of Class DesignPrinciplePurposeSingle Responsibility PrincipleA class should have one, and only one, reason to change.Open Closed PrincipleYou should be able to extend a classs behavior without modifying it.Liskov Substitution PrincipleDerived classes must be substitutable for their base classes.Interface Segregation PrincipleMake fine grained interfaces that are client specific.Dependency Inversion PrincipleDepend on abstractions, not on concretions.http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOodSingle Responsibility Principlehttp://tinyurl.com/ahap3jPosters by Derick Bailey</p> <p>Things that need to be tested.Goal: test your application without running the UIComboBox / ListBoxPopulation of listsSelection logicField-based logicValue, Visibility, ValidationDependencies between fieldsMessageBoxes Alerts and exceptionsProgressBar logicModel to Data AccessViewModel to Model</p> <p>Overview of unit testing.What is a Unit Test?Piece of code that verifies that another piece of codeTest code verifies application code</p> <p>What is Test-Driven Development (TDD)?Practice of developing code so that you always have proof that the code is workingMindset</p> <p>Never write a single line of code unless you have a failing automated test. -Kent Beck (Test-Driven Development, Addison-Wesley)Why Write Unit Tests?High-quality codeFewer bugsClean designClean codeProfessional ResponsibilityProof that your code worksNotification when your code is brokenQuality focus throughout the development cycleSide EffectsCode is easier to maintain, refactorSelf-documentingUnit testing problems and solutions.ProblemsExtra code for the sake of the testTons of setup code required to run the testUser Interfaces Best case: Hard to testWorst case: Impossible to test</p> <p>SolutionsPlan for testabilityBuild a testable architecture</p> <p>Mocks &amp; StubsDependency InjectionModel-View-ViewModel</p> <p>Plan for testability? If you build it, it needs to be tested.If you can test it with an automated test, its better.When you build, think of how to test it.The architecture changes when you think about how to test.</p> <p>It is important to remember theSingle Responsibility PrincipleSo what is this MVVM thing?Overview of MVVM.What is MVVM?Model-View-ViewModelUser interface interaction design patternCousin of Model-View-Controller (MVC)Enabled by data binding in WPF, Silverlight, WP7Why use MVVM?or MVC or MVP?</p> <p>Keep code organizedSeparate UI implementation from the logicKeep code out of the code behind (*.xaml.cs)Hint: this enables Design for Testability</p> <p>Our To Do listArchitect the Silverlight Async solutionRe-usable fieldsValues, Visibility, and ValidationList-based fieldsComboBox and ListBoxMessageBoxesProgressBarsViewModel to ModelModel to Data Access</p> <p>Tip: If youre writing Silverlight,figure out your async solution early.Network traffic in SilverlightIt has to be async.If it isnt, the UI thread locksforever.My initial client-side architecture.</p> <p>My architecture after Async WCF beat me up and ate my lunch.</p> <p>Async KillsYour Repository methods cant return populated objects must return voidException handling is hardWork happens on a different threadExceptions cant bubble up the stackYou could have your *.xaml.cs handle the callbacks UglyViolates separation of concernsNot very testableLonger discussion of Silverlight asynchttp://blog.benday.com/archive/2010/12/24/23300.aspx</p> <p>My Solution: ReturnResultVirtual call stackNotify(Exception) or Notify(T)</p> <p>The glue between method calls</p> <p>Reactive Extensions for .NET http://msdn.microsoft.com/en-us/devlabs/ee794896.aspxAlternate SolutionOur To Do listArchitect the Silverlight Async solutionRe-usable fieldsValues, Visibility, and ValidationList-based fieldsComboBox and ListBoxMessageBoxesProgressBarsViewModel to ModelModel to Data Access</p> <p>Primitive Obsession in your ViewModel.Primitive ObsessionJames Shores Primitive ObsessionToo many plain scalar valuesPhone number isnt really just a stringhttp://www.jamesshore.com/Blog/Validation in the get / set properties is ok but is phone number validation really the responsibility of the Person class? </p> <p>Coarse-Grained vs. Fine-GrainedObject ModelJames Shore blog entry talks about ResponsibilitiesFine-grained = More object-orientedData and properties are split into actual responsibilities </p> <p>Im concerned about Responsibilities Code Duplication SimplicityViewModelFieldProvides common functionality for a property on a ViewModel</p> <p>With &amp; Without ViewModelField</p> <p>Are your ViewModel propertiesCoarse or Fine?Fine-grained gives you room to growViewModelFieldCreate custom controls that know how to talk to your ViewModelFieldsSimplified binding expressionsAdd features laterField validation laterSecurityViewModelFieldDemo ComboBox &amp; ListBOXDemo MESSAGE BOXESDemo Progress BarsDemo Our To Do listArchitect the Silverlight Async solutionRe-usable fieldsValues, Visibility, and ValidationList-based fieldsComboBox and ListBoxMessageBoxesProgressBarsViewModel to ModelModel to Data Access</p> <p>Focus your testing on stuff that tends to be buggy.Calls to data access are buggy.The goal: Data access should take/return Model objects.</p> <p>DatabasesADO.NET objects dont look like your ModelMake the db call, convert the data to ModelsTake the Model, convert it to a db callWCF ServicesService Reference classes *are not* your modelMake a WCF call, convert the data to ModelsTake the Model, make a WCF call</p> <p>This stuff is always buggy.Repository &amp; Adapter Patterns are your friendWhat is Repository?The Repository PatternMediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.http://martinfowler.com/eaaCatalog/repository.html Encapsulates the logic of getting things saved and retrieved</p> <p>Synchronous Repository</p> <p>Synchronous SQL Server &amp; WCF</p> <p>A Big Picture</p> <p>What is Adapter?Adapter Patternconverts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldnt otherwise because of incompatible interfaces.from Head First Design Patternsby Elisabeth &amp; Eric Freeman</p> <p>My version of Adapter PatternTake object of Type A and convert it in to object of Type BWhy are these patterns your friend?If you Add Service Reference, these are *NOT* your Models or ViewModels(I know it might be tempting.)(Remember, its 2 applications.)$0.02, you want your own Models and ViewModelsBreaks the dependency on the WCF servicesYoull convert to/from the Service Reference objectsWhy are these patterns your friend?Help focus your mindBetter designHelp contain bugsThese conversions to/from will be buggyHelp localize changeService endpoint designs will change oftenUnit test the conversions separately(Remember its a unit test.)</p> <p>Keep the Adapt separated from the RetrieveTwo classesRepository knows how to talk to the WCF serviceAdapter knows how to turn the Service Reference types into ModelsSingle Responsibility Principle (SRP)</p> <p>Repository &amp; ADAPTERdemoOur To Do listArchitect the Silverlight Async solutionRe-usable fieldsValues, Visibility, and ValidationList-based fieldsComboBox and ListBoxMessageBoxesProgressBarsViewModel to ModelModel to Data Access</p> <p>No shortcuts: Keep your ViewModels &amp; Models separate.No shortcuts: Keep your ViewModels &amp; Models separate.It will be tempting to have your Repository/Adapter layer create ViewModels(Dont.)Theres a reason why its calledModel-View-ViewModelWhy keep Model and ViewModel separated?ViewModel is a user interface designModel is the state of your applicationaka. Domain Model patternViewModel advocates for the UI1-to-1 between a ViewModel and a *.xaml fileMight reference multiple Models</p> <p>Dont have the ViewModel fields directly update the Model.</p> <p>Its all about the Cancel button.If youre two way data bound, How do you undo?</p> <p>Cancel: ViewModel wraps ModelViewModel populatesitself from the ModelUser edits the screen,ViewModel gets updatedModel doesnt get changed until Save button is clicked.</p> <p>Model is The Boss.</p> <p>ViewModel to ModelAdapterdemoSummary: Our To Do listArchitect the Silverlight Async solutionRe-usable fieldsValues, Visibility, and ValidationList-based fieldsComboBox and ListBoxMessageBoxesProgressBarsViewModel to ModelModel to Data Access</p> <p>Thank you.blog.benday.com | www.benday.com | benday@benday.com</p> <p>Other Resourceshttp://tinyurl.com/3d2soe8</p> <p>Other Resourceshttp://tinyurl.com/ln248h </p> <p>Other Resourceshttp://tinyurl.com/3pf8vxd </p>