Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

I’m just finished with the green phase meaning all my tests pass. That means I can refactor. I do have some redundant code in my tests, so i think I will refactor them to make them a little more readable. Here are my tests now:

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

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

'@TestMethod("Count Changes")
Private Sub WhenTwoFieldsAreChangedThenReturnTwoEntryListOfChanges()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As New Collection
    Set testFormAuditor = New FormAuditor
    Randomize Timer
    NewForm.TestText = "New Thing " & Rnd()
    NewForm.Dirty = False
    NewForm.TestText = "New Thing " & Rnd()
    NewForm.Dirty = False
    Set testCollection = testFormAuditor.ListOfChanges
    Assert.AreEqual CLng(2), testCollection.Count
End Sub

I think just a very simple refactoring to extract the random TestText changes to a function. I did this and find my brain now spinning it’s wheels. I think there is more I could do, but I want to move on to a test. So here’s my current refactoring:

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

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

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

Private Sub ChangeTestText()
    Randomize Timer
    NewForm.TestText = "New Thing " & Rnd()
    NewForm.Dirty = False
End Sub

Putting on my red hat (for the create a failing test phase), I will now consider actually tracking a change with my FormAuditor. I know I will want to receive a list of the changes and be able to see what changes were made to which field. I currently only have one field on my form, so we will just use that for now.

At this point I’m interested in digging deeper into the returned collection to get the field name, the old value, the new value, and the date/time of the change.

Each Before Update event is triggering a new collection right now. Ooh, I just thought of an edge case though for our current system. If someone has not actually changed the value, I don’t want to receive that as a change (same old value and new value with just a timestamp).

Given: the Form Auditor control
When: a field is saved but the value is not changed
Then: an empty list of changes is returned

Let’s put that into a test (and I’ll update my ChangeTestText function with an optional new value to accomodate):

'@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

Private Sub ChangeTestText(Optional NewValue As String = "")
    If NewValue = "" Then
        Randomize Timer
        NewForm.TestText = "New Thing " & Rnd()
    Else
        NewForm.TestText = NewValue
    End If
    NewForm.Dirty = False
End Sub

Victory! I have a failing test:

Now, to make it pass tomorrow.