TDD is all about small changes and then testing and making sure things continue to run. I made the mistake yesterday of trying to refactor too much at once and I ended up leaving my system in an unrunnable state.
Ideally, as you are developing, each change you make is a potentially releasable candidate for your software, so you want to keep it working and not leave it or commit it in a broken state.
So, I’m going to continue to work on the function I was refactoring yesterday, first getting it into a working state as quickly as I can and then continuing to refactor. Right now I am refactoring a test and I left it at this with the test, then the helper function I was refactoring to:
'@TestMethod("Verify Changes")
Private Sub WhenTwoTextFieldsChangeBeforeAndAfterValuesAreReturned()
Dim testCollection As New Collection
Dim TestTextChange As New AuditFieldChange, TestComboChange As New AuditFieldChange
Set testCollection = testFormAuditor.ListOfChanges
Set TestTextChange = testCollection.Item(1).FieldChanges("TestText")
Set TestComboChange = testCollection.Item(1).FieldChanges("TestCombo")
Assert.IsTrue TestTextChange.OldValue = "TextBeforeValue" And TestTextChange.NewValue = "TextAfterValue" And TestComboChange.OldValue = "ComboBeforeValue" And TestComboChange.NewValue = "ComboAfterValue"
End Sub
Private Function SetFields_ChangeThem_ReturnListOfChanges(ParamArray arrFieldName_SetVal_NewVal() As Variant) As Collection
Dim testFormAuditor As FormAuditor
Dim arr As Variant
For Each arr In FieldChanges
NewForm(arr(0)) = arr(1)
Next arr
ChangeFields Array("TestText", "TextBeforeValue"), Array("TestCombo", "ComboBeforeValue")
Set testFormAuditor = New FormAuditor
ChangeFields Array("TestText", "TextAfterValue"), Array("TestCombo", "ComboAfterValue")
End Function
This doesn’t compile, first complaining about the variable not being defined that I am setting in the Test Method “testFormAuditor”. I’m going to change that so it is expecting the new function to return the list:
'@TestMethod("Verify Changes")
Private Sub WhenTwoTextFieldsChangeBeforeAndAfterValuesAreReturned()
Dim testCollection As New Collection
Dim TestTextChange As New AuditFieldChange, TestComboChange As New AuditFieldChange
Set testCollection = SetFields_ChangeThem_ReturnListOfChanges()
Set TestTextChange = testCollection.Item(1).FieldChanges("TestText")
Set TestComboChange = testCollection.Item(1).FieldChanges("TestCombo")
Assert.IsTrue TestTextChange.OldValue = "TextBeforeValue" And TestTextChange.NewValue = "TextAfterValue" And TestComboChange.OldValue = "ComboBeforeValue" And TestComboChange.NewValue = "ComboAfterValue"
End Sub
Now that function is compiling (yes it would never work yet, but compiling is my first hurdle). And now the helper function won’t compile because FieldChanges isn’t defined. I had simply copied this loop from another function so the variable names aren’t changed yet. I want this to loop over the Parameter array and change all the fields.
Private Function SetFields_ChangeThem_ReturnListOfChanges(ParamArray arrFieldName_SetVal_NewVal() As Variant) As Collection
Dim testFormAuditor As FormAuditor
Dim arr As Variant
For Each arr In arrFieldName_SetVal_NewVal
ChangeFields (arr(0))
Next arr
ChangeFields Array("TestText", "TextBeforeValue"), Array("TestCombo", "ComboBeforeValue")
Set testFormAuditor = New FormAuditor
ChangeFields Array("TestText", "TextAfterValue"), Array("TestCombo", "ComboAfterValue")
End Function
I changed the loop to use the ParamArray object and am just sending the first passed array of field info to the ChangeFields argument. And now the code compiles. My stress level just went down. Whew.
Ok, I have a problem here though in that I want to pass ALL of the arguments passed into my initial array through to the ChangeFields function. Can I do this in VBA? Here is someone who has asked the same question (or wants the same effects) in StackOverflow:
vba – Pass array to ParamArray – Stack Overflow
And the verdict from this StackOverflow is basically, no, not easily, you have to pass the whole paramarray as a series of arrays and then pull it out of the single array and re-process the arguments. Ugly and not elegant.
Since I’m using a dictionary of field names with their arrays I could just build my expected resulting dictionary, pass that to a function to process it on the form, and see if the form comes back with the same dictionary.
I’m wondering if then just becomes a test in exercising that my code works the way it works. I don’t think so, it’s just using the result I want to achieve to try to update the form that way and see if it produces the expected result. Ok, that’s what I’ll do. Next time I will create the dictionary object I am expecting to see and make sure that’s what’s coming back…