• Save
Mock Objects, Design and Dependency Inversion Principle
Upcoming SlideShare
Loading in...5
×
 

Mock Objects, Design and Dependency Inversion Principle

on

  • 1,458 views

 

Statistics

Views

Total Views
1,458
Slideshare-icon Views on SlideShare
1,452
Embed Views
6

Actions

Likes
2
Downloads
0
Comments
0

1 Embed 6

http://www.linkedin.com 6

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Mock Objects, Design and Dependency Inversion Principle Mock Objects, Design and Dependency Inversion Principle Presentation Transcript

    • Mock Objects, Design andDependency 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 stubs properties will automatically behave like normal properties, and you cant set expectations on them. – provide canned answers to calls made during the test, usually not responding at all to anything outside whats 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 isnt 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
    • ProblemHigh level class have to be changed and updated every time the low-level-class interfaceis changed, added or removed. So, High level class is not reusable when low-level-classesdefines interfaces which high level class is depended on. High Level ClassHigher layer Interface InterfaceLower 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 InterfaceHigher layer Low Level Class Low Level Class Low Level ClassLower 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 InversionThis 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 IMammalHuman Elephant Giraffe
    • Provider modelProvider Consumer Provider Provider Provider IService ConsumerProvider 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.