Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

As I am continuing on my Test Driven Development journey, I am starting to learn how to write tests as I add new features to my code. A recent example would be a requirement to ask for a password if the user was trying to delete a line in an order. There are additional requirements about the type of line it is and whether it has child elements, but let’s ignore that for the sake of this test case.

The difficult thing I’ve found with testing my existing code is just figuring out how to write a test to solve the condition.

In this case, I need to set up a test by creating a certain kind of line (all based on either database entries or what is being read from the form itself) and then testing whether it is in a certain grouping, and finally whether one of the members of the group is read-only or not. In that case I want to ask for a password before deleting it.

Ultimately the test is very simple, it’s setting up the criteria for the test, and then making sure that the same live code will be used that the test is using.

So to summarize briefly, at the highest level, I need to:

  1. Verify that the criteria is met.
  2. Verify that a password is asked for.
  3. The same code should be able to be running under test and in live.

In order to do this, I need to be able to set up my own criteria that can pass the criteria tests, and sense whether the password is asked for.

I want this test to be automated, so I don’t want to actually pop up a password dialog box.

I am using the RubberDuckVBA Unit Testing framework. Let’s look at the test I ended up writing:

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

Tomorrow I will start breaking down this example and explaining some of the changes I had to do to get the central function I am testing able to be tested. This central function is “LineController.ExecFormDelete”.