SlideShare une entreprise Scribd logo
1  sur  22
Mock Objects,
        Design and
Dependency Inverting Principle




                           P. Heinonen 2011
What are mock objects?
• Object oriented crash test dummies
• In a unit test mock objects can simulate the
  behavior of complex, real (non-mock) objects
• technique that allow you to isolate classes from
  their dependencies for testing purposes.
• allows fine-grained testing even before the
  dependent classes are fully implemented
• normal assertion in unit test verifies the state but
  with Mock objects test verifies behavior
• many practices in TDD and BDD
Mocks and Stubs
•   A mock is an object that
     – can have expectations
     – will verify that the expected actions have indeed occurred.
     – Is pre-programmed with expectations which form a specification of the calls they are expected
       to receive
•   A stub is an object that
     – you use in order to pass to the code under test.
     – which you can setup expectations, so it would act in certain ways, but those expectations will
       never be verified. A stub's properties will automatically behave like normal properties, and
       you can't set expectations on them.
     – provide canned answers to calls made during the test, usually not responding at all to anything
       outside what's programmed in for the test.

•   If you want to verify the behavior of the system under test, you will use a mock
    with the appropriate expectation, and verify that. If you want just to pass a value
    that may need to act in a certain way, but isn't the focus of this test, you will use a
    stub.
    IMPORTANT: A stub will never cause a test to fail.
When to mock?
• when creating effective unit tests
• when testing object behaving
• when a real object is impractical or impossible to incorporate into a
  unit test
• For example in cases where real-object:
    – supplies non-deterministic results (e.g., the current time or the
      current temperature)
    – has states that are difficult to create or reproduce (e.g., a network
      error)
    – is slow (e.g., a complete database, which would have to be initialized
      before the test)
    – does not yet exist or may change behavior
    – would have to include information and methods exclusively for testing
      purposes (and not for its actual task)
Unit test principles
• Test only one thing per test
• each unit test should validate no more than
  one significant interaction with another
  object. This generally implies that a given test
  should have no more than one mock object,
  but it may have several stubs, as needed
• Unit test is test which is only in memory, is fast
  and repeatable and does not touch in any
  external resources
Mocking drives your design
• Mocks force you to think dependencies that
  your classes and methods have.
• It forces to think about coupling between
  classes and drives the design to better one.
• Loosely coupled design makes testing and
  using Mock objects much easier.
• Thinking design early helps you to easily
  manage code changes over time.
Mocking Frameworks
•   Moq
•   Rhino Mocks
•   EasyMock
•   TypeMock
•   Microsoft Fakes (formerly Moles)
•   NMock
Unit test with Rhino Mock
[Test(Description = @"Registering new call and saves the call to the CallRepository")]
public void RegisterNewWorkshopCall_SaveTheCall_WhenCallIsValid()
{
  // There should be three steps in good unit test: Arrange, Act, Assert. "AAA syntax"
  // First you arrange the state, then you execute the code under test and
  // finally you assert that the expected state change or behavior happened.

    // ARRANGE
    ICallRepository mockCallRepository = MockRepository.GenerateMock<ICallRepository>();
    ICallValidator mockCallValidator = MockRepository.GenerateMock<ICallValidator>();
    // controlling program flow by specifying stub
    mockCallValidator.Stub(x => x.IsValid(Arg<Call>.Is.Anything)).Return(true);

    // create SUT (System Under Test with dependency Injecting two mocks)
    var callRegistrationService = new CallRegistrationService(mockCallRepository, mockCallValidator);
    var call = new Call{Id = 123,Gateway = Gateway.EOBD,Parameter = new Parameter()};

    // ACT
    callRegistrationService.RegisterNewCall(call);

    // ASSERT
    mockCallRepository.AssertWasCalled(x => x.Save(call));
}
For the sake of good design
• Good design is better than bad design
• Loosely coupled objects are usually a better
  design than tightly coupled objects
• Testing improves code quality and developer
  efficiency over time
• Testing is easier with a loosely coupled designs
• Managing changes are easier when you have
  good sets of unit tests
Dependency Inversion Principle
• Inverting the design where lower level modules
  defining interface that higher level modules depend
  on.
• So we get; higher level modules which define
  interfaces that lower level modules implement

        ”High-level modules should not depend on low-
        level modules. Both should depend on
        abstractions. Abstraction should not depend upon
        details. Details should depend upon abstractions.”
        - Founder of SOLID principles, Bob Martin
Problem
High level class have to be changed and updated every time the low-level-class interface
is changed, added or removed. So, High level class is not reusable when low-level-classes
defines interfaces which high level class is depended on.



                                   High Level Class
Higher layer




                         Interface                    Interface


Lower layer
                     Low Level Class             Low Level Class
Solution: Inverting Dependency
  High level class defines interface which low-level-classes implement.
  Basically what High level class tells to low-level-classes is that:
  ”you have to implement this interface if I’m going to use you to do this job”.
  Also, now it is possible to add more low-level implementation without changing
  the High level classHigh level class becomes reusable.



                    High Level Class                Interface
Higher layer




                               Low Level Class
                                Low Level Class
                                  Low Level Class
Lower layer                        Low Level Class
Dependency Inversion principle
              example
 WRONG!

Button       Lamp




                          RIGHT!

                     Button        IButtonClient



                    ButtonImpl        Lamp
Inversion of Control
• ”IoC” is a high level practice and design guideline for removing
  dependencies in your code.
• aka. Hollywood principle: ”Don’t call us, we call you”
• Can be used in different ways
    – Control over interface between two systems or components
    – Control over the flow of an application
    – Control over dependency creation and binding
• Serves the following purposes:
    – There is a decoupling of the execution of a certain task from
      implementation.
    – Every module can focus on what it is designed for.
    – Modules make no assumptions about what other systems do but rely
      on their contracts.
    – Replacing modules has no side effect on other modules.
Example of IoC patterns
•   Dependency Inversion Principle ”DIP”
•   Interface Inversion
•   Flow Inversion (not explained here)
•   Create Inversion
Interface Inversion
This is anti-pattern: Don’t over use Interfaces




     IHuman                GameOfLife
        Human


         IElephant
           Elephant


                           IGiraffe
                              Giraffe
Interface Inversion
 Interfaces should have more than 1 implementation!


                                       GameOfLife

              IMammal




Human         Elephant       Giraffe
Provider model

Provider         Consumer
 Provider
   Provider
     Provider




      IService   Consumer




Provider
 Provider
   Provider
     Provider
Creation Inversion
• Reduce use of switch-statements, eh more than
  that...
• Normally you create object like:
   – MyClass mObject = new MyClass();
• Or with interface:
   – IMyInterface myObject = new MyImplementation();
• With inverting control you will...
   – Create object outside of the class they are being used
   – Create objects outside of objects in some central
     place, like a factory patternavoid copy&paste
     coding and tight dependencies+maintenance horror
Some Creation Inversion types
• Factory Pattern
  – Payment payment = InvoiceFactory.CreatePayment();

• Service Locator
  – Payment payment = ServiceLocator.Create(IPayment);

• Dependency Injection ”DI”
  – Payment payment = GetThePayment();
  – InvoiceController controller = new InvoiceController(payment);
  – Moves the creation and binding of a dependency outside of the class
    that depends on it. Common way to create loose coupling
Use common sense with DI
• Dependency Injection drives to good design
  but it has also cons and caveats when using
  too much:
  – Dependency Injection would expose internal
    implementation of class
  – DI also violates encapsulation
  – Dependencies created before needed
  – Large object graphs
• So, Watch out for too many dependencies!
Summary
• Depency Inversion Principle ”DIP” is a principle to
  guide software design to think dependencies between
  higher and lower level modules.
• IoC is a set of practices and patterns which help us to
  achieve the ”DIP” and see the benefits of changing
  dependencies.
• Think before using IoC; do you have good reason, what
  kind of dependency inversion you need and why?
• Every time using IoC you are inverting the Control in
  your design and that mean that you are taking control
  out of objects and interfaces or some other ways
  changing the control.

Contenu connexe

Tendances

ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
宏毅 李
 

Tendances (20)

確率ロボティクス第13回
確率ロボティクス第13回確率ロボティクス第13回
確率ロボティクス第13回
 
인공지능개론 (머신러닝 중심)
인공지능개론 (머신러닝 중심)인공지능개론 (머신러닝 중심)
인공지능개론 (머신러닝 중심)
 
Generative models (Geek hub 2021 lecture)
Generative models (Geek hub 2021 lecture)Generative models (Geek hub 2021 lecture)
Generative models (Geek hub 2021 lecture)
 
[SOSCON 2017] 주니어 개발자 5000명, 개발 해서 남 주자
[SOSCON 2017] 주니어 개발자 5000명, 개발 해서 남 주자[SOSCON 2017] 주니어 개발자 5000명, 개발 해서 남 주자
[SOSCON 2017] 주니어 개발자 5000명, 개발 해서 남 주자
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
 
人工知能を用いた医用画像処理技術
人工知能を用いた医用画像処理技術人工知能を用いた医用画像処理技術
人工知能を用いた医用画像処理技術
 
Generative Adversarial Networks
Generative Adversarial NetworksGenerative Adversarial Networks
Generative Adversarial Networks
 
Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出Pynqでカメラ画像をリアルタイムfastx コーナー検出
Pynqでカメラ画像をリアルタイムfastx コーナー検出
 
Introduction to Skia by Ryan Chou @20141008
Introduction to Skia by Ryan Chou @20141008Introduction to Skia by Ryan Chou @20141008
Introduction to Skia by Ryan Chou @20141008
 
[DL輪読会]医用画像解析におけるセグメンテーション
[DL輪読会]医用画像解析におけるセグメンテーション[DL輪読会]医用画像解析におけるセグメンテーション
[DL輪読会]医用画像解析におけるセグメンテーション
 
170420 東工大授業「ロボット技術」資料
170420 東工大授業「ロボット技術」資料170420 東工大授業「ロボット技術」資料
170420 東工大授業「ロボット技術」資料
 
Introduction to Spiking Neural Networks: From a Computational Neuroscience pe...
Introduction to Spiking Neural Networks: From a Computational Neuroscience pe...Introduction to Spiking Neural Networks: From a Computational Neuroscience pe...
Introduction to Spiking Neural Networks: From a Computational Neuroscience pe...
 
차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)차원축소 훑어보기 (PCA, SVD, NMF)
차원축소 훑어보기 (PCA, SVD, NMF)
 
Action Recognitionの歴史と最新動向
Action Recognitionの歴史と最新動向Action Recognitionの歴史と最新動向
Action Recognitionの歴史と最新動向
 
ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
ICASSP 2018 Tutorial: Generative Adversarial Network and its Applications to ...
 
GPU と PYTHON と、それから最近の NVIDIA
GPU と PYTHON と、それから最近の NVIDIAGPU と PYTHON と、それから最近の NVIDIA
GPU と PYTHON と、それから最近の NVIDIA
 
【Unity道場 名古屋SP】HMI及び自動運転におけるUnity活用事例
【Unity道場 名古屋SP】HMI及び自動運転におけるUnity活用事例【Unity道場 名古屋SP】HMI及び自動運転におけるUnity活用事例
【Unity道場 名古屋SP】HMI及び自動運転におけるUnity活用事例
 
Normalization 방법
Normalization 방법 Normalization 방법
Normalization 방법
 
物体検出エラーの分析ツール TIDE
物体検出エラーの分析ツール TIDE物体検出エラーの分析ツール TIDE
物体検出エラーの分析ツール TIDE
 
物体検出フレームワークMMDetectionで快適な開発
物体検出フレームワークMMDetectionで快適な開発物体検出フレームワークMMDetectionで快適な開発
物体検出フレームワークMMDetectionで快適な開発
 

Similaire à Mock Objects, Design and Dependency Inversion Principle

Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Code
jameshalsall
 
Coldbox developer training – session 4
Coldbox developer training – session 4Coldbox developer training – session 4
Coldbox developer training – session 4
Billie Berzinskas
 
AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
Miklos Csere
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
Alex Borsuk
 
Type mock isolator
Type mock isolatorType mock isolator
Type mock isolator
MaslowB
 

Similaire à Mock Objects, Design and Dependency Inversion Principle (20)

Dependency Injection in .NET applications
Dependency Injection in .NET applicationsDependency Injection in .NET applications
Dependency Injection in .NET applications
 
MongoDB World 2018: Tutorial - MongoDB Meets Chaos Monkey
MongoDB World 2018: Tutorial - MongoDB Meets Chaos MonkeyMongoDB World 2018: Tutorial - MongoDB Meets Chaos Monkey
MongoDB World 2018: Tutorial - MongoDB Meets Chaos Monkey
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Writing Testable Code
Writing Testable CodeWriting Testable Code
Writing Testable Code
 
Weekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design PatternWeekly Meeting: Basic Design Pattern
Weekly Meeting: Basic Design Pattern
 
Unit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - KenyaUnit testing and mocking in Python - PyCon 2018 - Kenya
Unit testing and mocking in Python - PyCon 2018 - Kenya
 
Dependency injection and inversion
Dependency injection and inversionDependency injection and inversion
Dependency injection and inversion
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014
 
Design p atterns
Design p atternsDesign p atterns
Design p atterns
 
Dependency Inversion Principle
Dependency Inversion PrincipleDependency Inversion Principle
Dependency Inversion Principle
 
Coldbox developer training – session 4
Coldbox developer training – session 4Coldbox developer training – session 4
Coldbox developer training – session 4
 
Mobile App Architectures & Coding guidelines
Mobile App Architectures & Coding guidelinesMobile App Architectures & Coding guidelines
Mobile App Architectures & Coding guidelines
 
Test Driven Development - Workshop
Test Driven Development - WorkshopTest Driven Development - Workshop
Test Driven Development - Workshop
 
AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
 
Unit testing
Unit testingUnit testing
Unit testing
 
Mvvm basics
Mvvm basicsMvvm basics
Mvvm basics
 
Type mock isolator
Type mock isolatorType mock isolator
Type mock isolator
 
Resilience and chaos engineering
Resilience and chaos engineeringResilience and chaos engineering
Resilience and chaos engineering
 

Dernier

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Dernier (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

Mock Objects, Design and Dependency Inversion Principle

  • 1. Mock Objects, Design and Dependency Inverting Principle P. Heinonen 2011
  • 2. What are mock objects? • Object oriented crash test dummies • In a unit test mock objects can simulate the behavior of complex, real (non-mock) objects • technique that allow you to isolate classes from their dependencies for testing purposes. • allows fine-grained testing even before the dependent classes are fully implemented • normal assertion in unit test verifies the state but with Mock objects test verifies behavior • many practices in TDD and BDD
  • 3. Mocks and Stubs • A mock is an object that – can have expectations – will verify that the expected actions have indeed occurred. – Is pre-programmed with expectations which form a specification of the calls they are expected to receive • A stub is an object that – you use in order to pass to the code under test. – which you can setup expectations, so it would act in certain ways, but those expectations will never be verified. A stub's properties will automatically behave like normal properties, and you can't set expectations on them. – provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. • If you want to verify the behavior of the system under test, you will use a mock with the appropriate expectation, and verify that. If you want just to pass a value that may need to act in a certain way, but isn't the focus of this test, you will use a stub. IMPORTANT: A stub will never cause a test to fail.
  • 4. When to mock? • when creating effective unit tests • when testing object behaving • when a real object is impractical or impossible to incorporate into a unit test • For example in cases where real-object: – supplies non-deterministic results (e.g., the current time or the current temperature) – has states that are difficult to create or reproduce (e.g., a network error) – is slow (e.g., a complete database, which would have to be initialized before the test) – does not yet exist or may change behavior – would have to include information and methods exclusively for testing purposes (and not for its actual task)
  • 5. Unit test principles • Test only one thing per test • each unit test should validate no more than one significant interaction with another object. This generally implies that a given test should have no more than one mock object, but it may have several stubs, as needed • Unit test is test which is only in memory, is fast and repeatable and does not touch in any external resources
  • 6. Mocking drives your design • Mocks force you to think dependencies that your classes and methods have. • It forces to think about coupling between classes and drives the design to better one. • Loosely coupled design makes testing and using Mock objects much easier. • Thinking design early helps you to easily manage code changes over time.
  • 7. Mocking Frameworks • Moq • Rhino Mocks • EasyMock • TypeMock • Microsoft Fakes (formerly Moles) • NMock
  • 8. Unit test with Rhino Mock [Test(Description = @"Registering new call and saves the call to the CallRepository")] public void RegisterNewWorkshopCall_SaveTheCall_WhenCallIsValid() { // There should be three steps in good unit test: Arrange, Act, Assert. "AAA syntax" // First you arrange the state, then you execute the code under test and // finally you assert that the expected state change or behavior happened. // ARRANGE ICallRepository mockCallRepository = MockRepository.GenerateMock<ICallRepository>(); ICallValidator mockCallValidator = MockRepository.GenerateMock<ICallValidator>(); // controlling program flow by specifying stub mockCallValidator.Stub(x => x.IsValid(Arg<Call>.Is.Anything)).Return(true); // create SUT (System Under Test with dependency Injecting two mocks) var callRegistrationService = new CallRegistrationService(mockCallRepository, mockCallValidator); var call = new Call{Id = 123,Gateway = Gateway.EOBD,Parameter = new Parameter()}; // ACT callRegistrationService.RegisterNewCall(call); // ASSERT mockCallRepository.AssertWasCalled(x => x.Save(call)); }
  • 9. For the sake of good design • Good design is better than bad design • Loosely coupled objects are usually a better design than tightly coupled objects • Testing improves code quality and developer efficiency over time • Testing is easier with a loosely coupled designs • Managing changes are easier when you have good sets of unit tests
  • 10. Dependency Inversion Principle • Inverting the design where lower level modules defining interface that higher level modules depend on. • So we get; higher level modules which define interfaces that lower level modules implement ”High-level modules should not depend on low- level modules. Both should depend on abstractions. Abstraction should not depend upon details. Details should depend upon abstractions.” - Founder of SOLID principles, Bob Martin
  • 11. Problem High level class have to be changed and updated every time the low-level-class interface is changed, added or removed. So, High level class is not reusable when low-level-classes defines interfaces which high level class is depended on. High Level Class Higher layer Interface Interface Lower layer Low Level Class Low Level Class
  • 12. Solution: Inverting Dependency High level class defines interface which low-level-classes implement. Basically what High level class tells to low-level-classes is that: ”you have to implement this interface if I’m going to use you to do this job”. Also, now it is possible to add more low-level implementation without changing the High level classHigh level class becomes reusable. High Level Class Interface Higher layer Low Level Class Low Level Class Low Level Class Lower layer Low Level Class
  • 13. Dependency Inversion principle example WRONG! Button Lamp RIGHT! Button IButtonClient ButtonImpl Lamp
  • 14. Inversion of Control • ”IoC” is a high level practice and design guideline for removing dependencies in your code. • aka. Hollywood principle: ”Don’t call us, we call you” • Can be used in different ways – Control over interface between two systems or components – Control over the flow of an application – Control over dependency creation and binding • Serves the following purposes: – There is a decoupling of the execution of a certain task from implementation. – Every module can focus on what it is designed for. – Modules make no assumptions about what other systems do but rely on their contracts. – Replacing modules has no side effect on other modules.
  • 15. Example of IoC patterns • Dependency Inversion Principle ”DIP” • Interface Inversion • Flow Inversion (not explained here) • Create Inversion
  • 16. Interface Inversion This is anti-pattern: Don’t over use Interfaces IHuman GameOfLife Human IElephant Elephant IGiraffe Giraffe
  • 17. Interface Inversion Interfaces should have more than 1 implementation! GameOfLife IMammal Human Elephant Giraffe
  • 18. Provider model Provider Consumer Provider Provider Provider IService Consumer Provider Provider Provider Provider
  • 19. Creation Inversion • Reduce use of switch-statements, eh more than that... • Normally you create object like: – MyClass mObject = new MyClass(); • Or with interface: – IMyInterface myObject = new MyImplementation(); • With inverting control you will... – Create object outside of the class they are being used – Create objects outside of objects in some central place, like a factory patternavoid copy&paste coding and tight dependencies+maintenance horror
  • 20. Some Creation Inversion types • Factory Pattern – Payment payment = InvoiceFactory.CreatePayment(); • Service Locator – Payment payment = ServiceLocator.Create(IPayment); • Dependency Injection ”DI” – Payment payment = GetThePayment(); – InvoiceController controller = new InvoiceController(payment); – Moves the creation and binding of a dependency outside of the class that depends on it. Common way to create loose coupling
  • 21. Use common sense with DI • Dependency Injection drives to good design but it has also cons and caveats when using too much: – Dependency Injection would expose internal implementation of class – DI also violates encapsulation – Dependencies created before needed – Large object graphs • So, Watch out for too many dependencies!
  • 22. Summary • Depency Inversion Principle ”DIP” is a principle to guide software design to think dependencies between higher and lower level modules. • IoC is a set of practices and patterns which help us to achieve the ”DIP” and see the benefits of changing dependencies. • Think before using IoC; do you have good reason, what kind of dependency inversion you need and why? • Every time using IoC you are inverting the Control in your design and that mean that you are taking control out of objects and interfaces or some other ways changing the control.