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.