Click here to Skip to main content
Click here to Skip to main content

How to use the new AAA syntax in Rhino Mocks 3.5 with VB.Net

, 6 Oct 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
An article on how to use the new AAA (Arrange, Act and Assert) syntax using VB.Net. And the difference between the new and the old syntax.

Introduction

Since the 3rd of October 2008, Ayende has released a new version of Rhino Mocks.

Rhino Mocks is "A dynamic mock object framework for the .Net platform. It's purpose is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing."

This version now supports the AAA (Arrange, Act and Assert) syntax.

The major feature in Rhino Mocks 3.5 is the AAA syntax. Arrange, Act, Assert is a classic way to setup your tests. First you arrange the state, then you execute the code under test, finally you assert that the expected state change happened.

Which makes it more easy to read and use. I will try to explain how to use it and show the difference between the old and the new syntax using VB.Net. This article is not about why and when you should use Mocks. This is also not an article on best practices. The Repository for example is kept light it is just there to explain things.

I will also write just on test to see if the service returns the correct something if it gets called. For this it needs to use the Repository implementation but because we don't want the test to go to the database I will Mock it out.

You can find me and some other bright people at LessThanDot

Prerequisites

  • I used Rhino Mocks 3.5 for this, which can be found here.
  • And NUnit 2.4.6.0, which can be found here.

Set up

For this example I will use A Service and a Repository. The Service calls the Repository to do the dirty work. Both also have an interface which is usually the easier way to Mock something.

First we create the IService and IRepository interfaces

Namespace Service
    Public Interface IService
        Function FindAllProducts() As IList(Of Model.Product)
    End Interface
End Namespace

Namespace Repository
    Public Interface IRepository(Of T)
        Function FindAll() As IList(Of T)
    End Interface
End Namespace

Now both Interfaces need an implementation. Nothing fancy, just a simple implementation. The Repository code is there just as an example. It won't even work. And it doesn't need to work because we are going to mock it out.

First the service. This simply calls the repository. It also takes a IRepository(Of Model.Product) as a parameter so that we can inject an implementation in it.

Namespace Service
    Public Class Service
        Implements IService

        Private _Repository As Repository.IRepository(Of Model.Product)

        Public Sub New(ByVal Repository As Repository.IRepository(Of Model.Product))
            _Repository = Repository
        End Sub

        Public Function FindAllProducts() As IList(Of Model.Product) _
                                 Implements IService.FindAllProducts
            Return _Repository.FindAll
        End Function
    End Class
End Namespace

And now an implementation of IRepository which we won't use in the tests.

Imports System.Data.SqlClient

Namespace Repository
    Public Class ProductRepository
        Implements IRepository(Of Model.Product)

        ''' <summary>
        ''' Here is where you would go to the database
        ''' </summary>
        ''' <returns>A list of Products</returns>
        ''' <remarks>
        Public Function FindAll() As System.Collections.Generic.IList(Of Model.Product) _
                          Implements IRepository(Of Model.Product).FindAll
            Dim _List As New List(Of Model.Product)
            Dim _con As New SqlConnection
            Dim _com As New SqlCommand
            Dim _reader As SqlDataReader
            _con.ConnectionString = "some connectionstring"
            _con.Open()
            _com.CommandText = "Select Name from product"
            _com.Connection = _con
            _reader = _com.ExecuteReader
            While _reader.Read
                _List.Add(New Model.Product(_reader.GetString(0)))
            End While
            Return _List
        End Function
    End Class
End Namespace</remarks>

The tests

Rhino Mocks 3.4

In the previous version of Rhino Mocks you used Replay and Verify syntax. So our test would look like this.

Imports NUnit.Framework
Imports Rhino.Mocks

Namespace MockedTest34
    <testfixture()> _
    Public Class TestService

#Region " Private members "
        Private _Mocker As MockRepository
#End Region

#Region " Setup and TearDown "
        <setup()> _
        Public Sub Setup()
            _Mocker = New MockRepository
        End Sub

        <teardown()> _
        Public Sub TearDown()
            _Mocker.ReplayAll()
            _Mocker.VerifyAll()
        End Sub
#End Region

#Region " Tests "
        <test()> _
        Public Sub Test_If_Service_Returns_A_List_Of_Products()
            Dim _Repository As Repository.IRepository(Of Model.Product) = _
                        _Mocker.DynamicMock(Of Repository.IRepository(Of Model.Product))()
            Dim _Service As Service.IService = New Service.Service(_Repository)
            Rhino.Mocks.Expect.Call(_Repository.FindAll).IgnoreArguments.Return(New List(Of Model.Product))
            _Mocker.ReplayAll()
            Assert.IsNotNull(_Service.FindAllProducts)
        End Sub
#End Region

    End Class
End Namespace</test()></teardown()></setup()></testfixture()>

You see here that we an Instance of MockRepository. That MockRepository will make us a Mock using the DynamicMock method. In this case we Mock the Repository. We then make our Service and we pass in our Mocked Repository. After that we set our Expectation. We expect that the Findall method will be called on the Repository. We now have to call The ReplayAll method on the MockRepository object. Lastly we assert if the service returns something, we don't really care what that may be but since our function must return an Ilist(Of Model.Product) we don't really have to check that.

Rhino Mocks 3.5

In the new version the old code still works Wink | ;-) . But we can (and should) use the newer AAA syntax instead. As you will see in the code example it is a bit simpler to use.

Imports Nunit.FrameWork
Imports Rhino.Mocks

Namespace MockedTest35
    ''' <summary>
    ''' A TestClass
    ''' </summary>
    ''' <remarks>
    <testfixture()> _
Public Class TestService

#Region " Tests "

        ''' <summary>
        ''' A Test
        ''' </summary>
        ''' <remarks>
        <test()> _
        Public Sub Test_If_Service_Returns_A_List_Of_Products()
            Dim _Repository As Repository.IRepository(Of Model.Product) = _
                MockRepository.GenerateMock(Of Repository.IRepository(Of Model.Product))()
            Dim _Service As Service.IService = New Service.Service(_Repository)
            _Repository.Stub(Function(e) e.FindAll).IgnoreArguments.Return(New List(Of Model.Product))
            Assert.IsNotNull(_Service.FindAllProducts)
        End Sub

#End Region

    End Class
End Namespace</test()></remarks></testfixture()></remarks>

First we see that we no longer have to make and instance of MockRepository. We will use the Static/Shared methods of MockRepository instead. To make the mock we use the GenerateMock method of the MockRepository. Then we pass that mocked object to a new Service. We set our expectations via an extension method called stub. it uses a lambda expression to decide which method will be called. We set the desired return value and we use IgnoreArguments although not really needed in this instance because findall has no arguments. After that we call the service method and see if it returns something.

As you can see the new method no longer needs the ReplayAll and VerifyAll syntax either.

I hope this explains the difference well enough for you to go out and use this wonderfull product.

Points of Interest

If you switch from Rhino Mocks 3.4 to Rhino Mocks 3.5 the compiler will complain that Expect has no such method on the lines where you have Expect.Call. This is easily solved by adding Rhino.Mocks. In front of it. this is caused by the fact that Ayende also added an Extension method with the same name and the compiler can't make the difference. Adding an imports doesn't help.

History

10/07/2008 First version

10/07/2008 Added a link to an AAA explanation article. And corrected some typos.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

chrissie1
Software Developer (Senior) NICC
Belgium Belgium
I am a forensic technician who does some programming on the side. So I spend 75% of my time programming so that my collegues have to do less work Wink | ;-) .
 
I use VB.Net and C# with SQL-server as the database.
I try to use DDD and TDD techniques whenever possible.
 
You can find me and a lot of other professionals at LesstThanDot. Where I also host my blog.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 7 Oct 2008
Article Copyright 2008 by chrissie1
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid