Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

Ok, opened up the FormAuditor database and ran the tests. Here’s where I’m at:

That test name is a mouthful! GivenFormAuditorWhenOneFieldIsChangedThenAuditorReturnsSingleListOfChanges

Given: FormAuditor
When: One Field Is Changed
Then: AuditorReturnsSingleListOfChanges

So my test again looks like this:

'@TestMethod("FormAuditor")
Private Sub GivenFormAuditorWhenOneFieldIsChangedThenAuditorReturnsSingleListOfChanges()
    Dim testFormAuditor As New FormAuditor
    Dim testDictionary As New Scripting.Dictionary
    Randomize Timer
    NewForm.TestText = "New Thing " & Rnd()
    NewForm.Dirty = False
    Set testDictionary = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(1), testDictionary.Count
End Sub

And yes, I think that name is a bit too long. I know I was defending my long names, but that one is sooo long it’s rather hard to comprehend without breaking it out into it’s components.

Anyway, renaming tests is something to do when refactoring, not when making a test pass, so let’s make this test pass!

I may need to add a little more code to the test eventually, but let’s see if I can make it work as is.

First I need to configure the FormAuditor to hook into the BeforeUpdate event of the form, so let’s give that a shot.

I’m adding a Private form variable to the FormAuditor class using the WithEvents keyword:

Private WithEvents FormToAudit As Access.Form

I’ve already instantiated the form we are going to use before the test runs, so I should just be able to connect to it when making the FormAuditor instance by using the Class_Initialize event.

Private Sub Class_Initialize()
    Set FormToAudit = Forms("TestForm")
    FormToAudit.BeforeUpdate = "[Event Procedure]"
End Sub

That should work for initialization. Now I’ll create the BeforeUpdate event in the FormAuditor class:

Private Sub FormToAudit_BeforeUpdate(Cancel As Integer)
    pListOfChanges.Add "ChangeHappened", FormToAudit.TestText.Value
End Sub

And for that to work, I’ll need to make a Private class variable for the dictionary and update the ListOfChanges public property to return this internal variable. Here is the full FormAuditor class now:

Option Compare Database
Option Explicit

Private WithEvents FormToAudit As Access.Form
Private pListOfChanges As New Scripting.Dictionary

Public Property Get ListOfChanges() As Scripting.Dictionary
    Dim retVal As Scripting.Dictionary
    Set retVal = pListOfChanges
    Set ListOfChanges = retVal
End Property

Private Sub Class_Initialize()
    Set FormToAudit = Forms("TestForm")
    FormToAudit.BeforeUpdate = "[Event Procedure]"
End Sub

Private Sub FormToAudit_BeforeUpdate(Cancel As Integer)
    pListOfChanges.Add "ChangeHappened", FormToAudit.TestText.Value
End Sub

I think this might pass, so I’ll make a go of it. Let’s see what happens:

Bummer, it didn’t pass. It’s not seeing a dictionary with one element.

I’ll try setting a break point in the BeforeUpdate FormAuditor event. I suspect it’s not firing. That didn’t help, so I set a break point in the Test instead and walked through it. I thought that the class initialize method would run when I used the New keyword when Dimming the testFormAuditor varaible, but as I stepped through the test code, the class initialize function didn’t run until I called testFormAuditor.ListOfChanges. By that time we had already changed the form. So, I’m going to change the test slightly to Set the testFormAuditor = New FormAuditor and see if that will run the class initialize method.

Here is the new code for the test:

'@TestMethod("FormAuditor")
Private Sub GivenFormAuditorWhenOneFieldIsChangedThenAuditorReturnsSingleListOfChanges()
    Dim testFormAuditor As FormAuditor
    Dim testDictionary As New Scripting.Dictionary
    Set testFormAuditor = New FormAuditor
    Randomize Timer
    NewForm.TestText = "New Thing " & Rnd()
    NewForm.Dirty = False
    Set testDictionary = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(1), testDictionary.Count
End Sub

I’ll see if that works next time.