Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

Time to do more test driven development!

So we left off last time thinking about doing a test to see if a dictionary object I am going to create to store the form field changes is a new object. I was trying to determine how to Assert that using RubberDuckVBA and I was running up against my self imposed writing time limit.

Now that we have another session, I started thinking about this already and there is absolutely no reason yet that I need to Assert that my object is an empty dictionary.

How about I just look at a count of the elements in the dictionary and make sure it’s zero. Much easier to Assert that. So that’s what I’ll do next.

'@TestMethod("FormIterator")
Private Sub IterateWhenNothingChangedReturnsEmptyDictionary()
    Dim FormIteratorTest As New FormIterator
    Dim testDictionary As Scripting.Dictionary
    FormIteratorTest.Setup NewForm
    Set testDictionary = FormIteratorTest.Iterate()
    
    Assert.IsTrue testDictionary.Count = 0 ' <- Just added
End Sub

Yes! Now I have a test which technically was already failing to compile. Why? Because it doesn’t like my reference to the Scripting.Dictionary object. This is because I never added the reference to the project.

Incidentally, I know some people have been discussing whether the Scripting object will continue to be in Access VBA or if it will be deprecated because the VBScript language is being deprecated. I won’t pretend to have any answers here on that because the Microsoft remarks at the time I reviewed them were quite vague, but I don’t see how it would be wise of them to pull out the DLL for the Microsoft Scripting Runtime. That has always been one I have considered “safe” to include in projects. Perhaps in the future it will be deprecated though. I will trust that the community will provide a multitude of feedback to Microsoft that it is a Bad Idea to deprecate it at least for now. If it goes away, then it will be time to find an alternative solution.

So, I’m adding Microsoft Scripting Runtime to my VBA references for this project. Alternatively I could use late binding instead. This has no effect on the potential deprecation, but it would allow me to compile without the reference added. But I want to see my dictonary object code autocomplete so I’m binding it early.

Ok, now I fail to compile again because I don’t have an Iterator method in my FormIterator object yet.

So now to make this test pass, I need the Iterate method to return a Scripting.Dictionary object.

So finally I move to my class to add the Iterate method (or function as VBA likes to call them):

Option Compare Database
Option Explicit

Public Sub Setup(theForm As Access.Form)
End Sub

Public Function Iterate() As Scripting.Dictionary
    Dim retVal As Scripting.Dictionary
    Set retVal = New Scripting.Dictionary
    Set Iterate = retVal
End Function

I think this will pass, but only one way to find out.

Woo-hoo, passed!

At this point I want to think about refactoring. Remember the TDD cycle -> Write a failing test, Write enough code for the test to pass, refactor.

So as I’m looking at the tests, I notice that I have a module: TestFormListener, but it is including FormIterator tests and FormListener tests AND I don’t need the same global setup for both. Even so, I don’t think I have enough coded here to determine the structure of all this yet.

I think what I will want to do is add a FormListener into the iterator? There needs to be a way to have the iterator check fields during the BeforeUpdate routine of the form. Am I thinking too far ahead? Perhaps. Looking forward to the next exciting chapter!