Showing posts with label unit test. Show all posts
Showing posts with label unit test. Show all posts

Friday, February 17, 2012

The difference between a Mock and a Stub

Many people have a lot of problems to understand the difference between a Mock and a Stub. Marting Fowler states that a Mock is about behaviour verification and a Stub is about state verification
From: http://martinfowler.com/articles/mocksArentStubs.html





  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. 


  • I am going to try to explain you in one simple example the difference...
    The classes involved:
    FileProcessor: The actual business logic, that we are trying to test, the Subject Under Test
    File: some file we are processing
    FileValidator: Performs some logic on the file to see if it contains errors
    FileMover: Moves the file to a specific location depending on the results returned by the FileValidator

    public class FileProcessor{
            private readonly IFileMover _FileMover;
            private readonly IFileValidator _FileValidator;

            //Constructor
            public FileProcessor(IFileMover fileMover, IFileValidator fileValidator){
                       IFileMover _FileMover = fileMover;
                       IFileValidator _FileValidator = fileValidator;
            }

            public void Process(File file){
                 ValidationResults result = _FileValidator.Validate(file);

                 if(result.IsValid){
                      _FileMover.Succes(file)
                 }else{
                      _FileMover.Error(file)
                  }
            }
    }

    public interface IFileMover{
           void Success(File file);
           void Error(File file);
    }

    public class ValidationResults{
                public virtual bool IsValid{
                     get;
                }
    }

    public interface IFileValidor{
           ValidationResults Validate(File file);
    }

    We need to create a dummy called DummyValidationResults

    public class DummyValidationResults: ValidationResults{
             public virtual bool IsValid{
                    get{ return false;}
             }
    }

    Now we create a Mock MockFileMover

    public class MockFileMover: IFileMover{

        public void Success(File file){
               this.SucessCalled++;
         }

        public void Error(File file){
             this.ErrorCalled++;
        }

        public int SuccesCalled{get; private set;}
        public int ErrorCalled{get; private set;}
    }

    We create a Stub named StubFileValidator

    public class StubFileValidator: IFileValidator{
         public ValidationResults Validate(File file){
            return new DummyValidationResult();
        }
    }


    now when we would like the test the Fileprocessor we can write:
        File aFile = new FakeFile();
        MockFileMover fileMover =  new MockFileMover()
        FileProcessor processor = new FileProcessor(new MockFileMover(), new StubFileValidator());
        processor.process(aFile);

        Assert.AreEqual(1,fileMover.ErrorWasCalled);
        Assert.AreEqual(0,fileMover.SuccessWasCalled);

    So what is the difference?
    The stub returns a predetermined answer what needs to happen and the path through the code dictates it will always be called. As you can see the methods of the mock are enclosed in decision logic in this case an if statement (this can as wel be a try catch switch or whatever), then we verify if the correct method on the mock has been called... so the mock is responsible for failing or succeeding the test...

    Tuesday, March 01, 2011

    EF CTP5 And Unit Testing

    Using Entity Framework Code First CTP5 its quite easy to write and unit test your repositories. However test should still be written against the mappings of the actual database. It would be best to split the tests that write to the database from the tests that read into a different class

    Just Create a class that inherits from DropCreateDatabaseAlways<T> override the seed method to create insert the values you want.
       1: public class DBContextInitializer : DropCreateDatabaseAlways<EntityContext>
       2: {
       3:     protected override void Seed(EntityContext context)
       4:     {
       5:         ProductDummies.GetAllProducts().ForEach(p => context.Set<Product>().Add(p));
       6:         context.Commit();
       7:     }
       8: }
    And then put in your Unit Test Assembly the following method:

       1: [ClassInitialize]
       2: public static void ClassInitialize(TestContext context) {
       3:     DbDatabase.SetInitializer(new DBContextInitializer());
       4: }

    If you then use an in memory database it will be fast. The best way to always start from a known state (and to avoid mstest concurrency problems is to put the following code in Your TestInitialize method:
       1: [TestInitialize]
       2: public void TestInitialize()
       3: {
       4:     string key = Guid.NewGuid().ToString();
       5:     TestContext.Properties.Add(DB_NAME_KEY, key);
       6:     repository = new Repository<Product>(key);
       7: }

    To delete put the following snippet in your TestCleanUp
       1: [TestCleanup]
       2: public void TestCleanUp()
       3: {
       4:     repository.Dispose();
       5:     DbDatabase.Delete(TestContext.Properties[DB_NAME_KEY].ToString);
       6: }

    Thursday, February 17, 2011

    Unit Testing ROI

    In my experience everybody knows for sure unit testing is a good thing. But then again it puzzles me why nobody is actually doing it... I think one of the biggest misconceptions is that everyone thinks that unit testing pays back over time or in the long run. This is not true! There is a more immediate payback on your investment that pays off from the very first line of code! The returns on Unit Testing grow exponentially over time...

    All projects go relatively smooth the first few months until they reach a certain point where the skeletons start falling out of the closet... Regression bugs start to appear at an alarming rate, it takes longer to detect errors, more time is spent in the debugger than actually writing code, it gets harder to add new functionality,etc,...

    Unit testing will:

    • Reduce the time spent in the debugger
    • Reduce time to test your code as a developer
    • Enables you to refactor

    Reduce the time spent in the debugger

    if you consistently write (good) unit tests you will be focusing on smaller portions of your code and thus preventing you to have to step through your whole application. When running all your unit tests you will automatically see when you break existing functionality, like this you will hunt down the likely cause a lot quicker (probably it was that last bit of code you changed).

    Reduce time to test your code as a developer

    When you unit test your code those little forms with one "test" button will be of the past. An other thing which will save you tremendous amounts of time is that it is no longer needed to step through a series of screens before you actually get to the functionality you want to test.

    Enabling refactoring

    If you have unit tests you can refactor those methods and classes that grow an keep growing... Everybody knows these little black holes in any application that are a pain to modify and every team member is reluctant to make modifications out of fear to break something else.

    NDepend Enables you to quickly identify where problems will start arising. Find below some useful queries.

    Types that are to big and need to be slimmed down

    WARN IF Count > 0 IN SELECT TYPES WHERE
       NbLinesOfCode > 500 OR
       NbILInstructions > 3000
       ORDER BY NbLinesOfCode DESC

    for more information: http://www.ndepend.com/Metrics.aspx#NbLinesOfCode

    Methods that are to big or to complex

    WARN IF Count > 0 IN SELECT METHODS WHERE
      ILCyclomaticComplexity > 40 AND
      ILNestingDepth > 4

    OR NbLinesOfCode > 50 //Can even be smaller
      ORDER BY ILCyclomaticComplexity DESC

    for more information: http://www.ndepend.com/Metrics.aspx#ILCC

    Thursday, March 18, 2010

    Error when running tests: Unable to load one or more of the requested types

    Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information..

    1. Clean the solution
    2. Close Visual studio
    3. Delete all the bin en obj folders
    4. Try again