Yesterday’s message:
Writing tests for legacy code – Part 3 | Access JumpStart
Before diving into the next piece of the function, the Act, here is the full code:
'@TestMethod("DeleteAction")
Private Sub GivenConcreteGroupDeleteTriggered_WhenReadOnlyStatusType_RequirePassword()
On Error GoTo TestFail
'Arrange:
Dim LineController As ECI_POLineController
Set LineController = New ECI_POLineController
Dim testDictionary As New Scripting.Dictionary
testDictionary.Add "Cost_Type_ID", "2"
testDictionary.Add "Product_Type_ID", "1"
testDictionary.Add "Qty_Ordered", "10"
testDictionary.Add "Phase_Number", "10"
testDictionary.Add "Item_Description", "Test Description"
testDictionary.Add "Qty_Used", "10"
testDictionary.Add "Unit_of_Measure", "EA"
testDictionary.Add "Taxable", "True"
testDictionary.Add "Concrete_Minutes_Apart", "15"
testDictionary.Add "Line_Status", STATUS_OPEN
'Act:
Dim frmGet As New FormValueGetter_Test
Dim PwCount As New T_PasswordsAlwaysTrueCounter
Set frmGet.FieldValues = testDictionary
Set LineController.frmGet = frmGet
Set LineController.Controller = New T_PoScreenControllerAddModeWritable
LineController.ExecFormDelete New T_StatusConcreteGroupLinesReadOnly, PwCount
'Assert:
Assert.AreEqual CLng(1), PwCount.Counter
TestExit:
'@Ignore UnhandledOnErrorResumeNext
On Error Resume Next
Exit Sub
TestFail:
Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
Resume TestExit
End Sub
So in parts 1 through 3, I explained what I’m testing, the naming process I’m using, the error handling, and the arranging of the test variables to pass. Next is the Act section:
'Act:
Dim frmGet As New FormValueGetter_Test
Dim PwCount As New T_PasswordsAlwaysTrueCounter
Set frmGet.FieldValues = testDictionary
Set LineController.frmGet = frmGet
Set LineController.Controller = New T_PoScreenControllerAddModeWritable
LineController.ExecFormDelete New T_StatusConcreteGroupLinesReadOnly, PwCount
Now, I suppose I could probably have just Dimmed the variables in the prior section and that could have been equally valid, but I chose to declare them just before I use them.
The FormValueGetter_Test is based on an Interface. An interface defines the public facing side of an object. When you implement an interface in a class object, it MUST contain ALL the public subs, functions, getters, setters, and variables that the interface specifies. This is so that I can guarantee That my “FormValueGetter_Test” class will have exactly the same calls available that the live “FormValueGetter” class has. So I can substitute my FormValueGetter from the live system which gets actual values from an actual form, with FormValueGetter_Test which I initialize with the values for the form that I want to be seen.
The same is true for T_PasswordsAlwaysTrueCounter. This is my test method in which it implements a Passwords Interface I created. The live version displays a password dialog box and only returns true if the user enters the correct password. The test version always returns true and counts the number of times it’s called.
So I have created the pieces of objects that need to be tested and created ways for me to define the inputs in the test environment which the user would have entered into the form and dialog box in the live environment.
The LineController.Controller is also loading a test PoScreenController which I have set to always return it is in “Add” mode and that the form is writable. These are things that the delete event needs to know before it can execute the actual LineController.ExecFormDelete function.
So all of these test objects were created and setup up specifically for this test to simulate what the app will actually encounter when it runs the ExecFormDelete function in the LineController. That is the live piece of code I’m testing.
Trackbacks/Pingbacks