Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

It is time to refactor the remaining counting tests. Here they are pre refactor:

'@TestMethod("Count Changes")
Private Sub WhenTwoFieldsAreChangedThenReturnTwoEntryListOfChanges()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As Collection
    Set testFormAuditor = New FormAuditor
    ChangeTestTextToRandomString
    ChangeTestTextToRandomString
    Set testCollection = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(2), testCollection.Count
End Sub

'@TestMethod("Count Changes")
Private Sub WhenOneFieldIsChangedToSameValueThenReturnNoListOfChanges()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As New Collection
    Set testFormAuditor = New FormAuditor
    ChangeTestText NewForm.TestText
    Set testCollection = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(0), testCollection.Count
End Sub

'@TestMethod("Count Changes")
Private Sub WhenFieldChangesFromNullToEmptyStringThenReturnOneEntryListOfChanges()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As New Collection
    ChangeTestText Null
    Set testFormAuditor = New FormAuditor
    ChangeTestText ""
    Set testCollection = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(1), testCollection.Count
End Sub

There are three tests to refactor using my simpler functions. And nuts, now that I’m looking at them, I’m not sure the first one will be able to use the new functions. I’m pretty sure I can do the middle one with no other refactoring, but the third one might also need me to allow null values in the input dictionary. Let’s do the middle one first:

'@TestMethod("Count Changes")
Private Sub WhenOneFieldIsChangedToSameValueThenReturnNoListOfChanges()
    Dim dctInputs As New Scripting.Dictionary, colResults As VBA.Collection
    dctInputs.Add "TestText", Array("Hello World", "Hello World")
    Set colResults = SetFields_ChangeThem_ReturnCollection(dctInputs)
    Assert.AreEqual CLng(0), colResults.Count
End Sub

That was pretty painless, just copied the One Field test I did yesterday and changed it slightly to reflect the conditions and test results I wanted and whoomp, there it is. Dropped by 2 lines and it’s clear what I’m doing I think.

Now let me see if I can do the same thing with the third test and pass a null in. And it worked and the test passed. Yay, nothing needed there other than the function refactor:

'@TestMethod("Count Changes")
Private Sub WhenFieldChangesFromNullToEmptyStringThenReturnOneEntryListOfChanges()
    Dim dctInputs As New Scripting.Dictionary, colResults As VBA.Collection
    dctInputs.Add "TestText", Array(Null, "")
    Set colResults = SetFields_ChangeThem_ReturnCollection(dctInputs)
    Assert.AreEqual CLng(1), colResults.Count
End Sub

That was great. Now for that first test which is making sure 2 elements get returned from the auditor representing 2 audit events (meaning it is running the BeforeUpdate routine twice).

The problem is that the SetFields_ChangeThem_ReturnCollection function will only do 1 event ever as it stands. It can’t do multiple BeforeUpdate events because it is explicitly creating a new form auditing object every time.

I am considering maybe passing an optional form auditing object to it. But I don’t generally like doing optional values because it violates the principle that a function should really do one thing.

Looking at this function:

Private Function SetFields_ChangeThem_ReturnCollection(dctFieldName_arrStartAndEndVals As Scripting.Dictionary) As VBA.Collection
    Dim testFormAuditor As FormAuditor
    ChangeFields dctFieldName_arrStartAndEndVals, 0
    Set testFormAuditor = New FormAuditor
    ChangeFields dctFieldName_arrStartAndEndVals, 1
    Set SetFields_ChangeThem_ReturnCollection = testFormAuditor.ListOfChanges
End Function

Basically, if I was passing in my own FormAuditor object and not creating a new one here, I’d be safe.

After doing some thinking and reviewing and attempting to change things, I came up with 2 functions. One that just takes a FormAudit object and 1 set of changes that the fields will be changed to. The other function sets the fields only. I’m also changing the names of the functions to reflect that they are returning the “ListOfChanges” collection vs a generic collection.

I’m out of time for today though, so I’m going to save finishing off the rest for another day.