I am working on this excellent tutorial, but in the end my first test is not passing, due to the fact that I can clearly see I am creating two different arrays (and pointers), and trying to compare them with one another.
Now the tutorial from what I can see leaves out a few lines of code that I have added, which is also where I see the problem, but without those lines the code does not even run of coarse.
All my other test methods are the same as the example, except for this method that I created the following lines - else nothing happens when you run the test.
Public Sub Run(ByVal dataService As IDataService, ByVal wsService As IWorksheetService)
Dim data As Variant 'Added this line
data = dataService.GetSomeTable 'Added this line
Call wsService.WriteAllData(data) 'Added this line
End Sub
And here is where I can see the code going south...
'@TestMethod
Public Sub WorksheetServiceWorksOffDataFromDataService()
'Arrange
Dim dataServiceStub As MyDataServiceStub
Set dataServiceStub = New MyDataServiceStub
Dim expected As LongLong
expected = VarPtr(dataServiceStub.GetSomeTable) 'expected creates an Array
Dim wsServiceStub As MyWorksheetServiceStub
Set wsServiceStub = New MyWorksheetServiceStub
'Act
With New MyTestableMacro
.Run dataServiceStub, wsServiceStub 'here we create a second array
End With
Dim actual As LongLong
actual = wsServiceStub.WrittenArrayPointer 'here we point to the address of the second array
'Assert
Assert.AreEqual expected, actual ' this test fails cause it points to two different addresses
End Sub
I had to change the type from Long as in the tutorial for the array pointers to LongLong due to the fact that the number on 64 bit is too long for Long. LongPtr also worked
The xlwings guys just demoed how to unit tests VBA functions in Python. Essentially, you do not need to add anything to your workbook but you rater write "stand alone" Python code that call your VBA functions so that you can compare expected vs actual results of your VBA functions.
The command requires users to skillfully step over each line of the VBA code in the second sub. If the code calls for another sub, simply step over the second sub and continue running the code. To run the code, press Shift+F8 simultaneously to execute the second sub. The stepping out command helps the user step out of the current running sub.
The Assert class in Rubberduck VBA provides some of the most commonly used assertions. Believe it or not, that’s it! We’re done with creating our first test case. Now starts the real fun: let’s run it. In order to run the test: Inside Test Explorer, click Run > All Tests.
The options we’ll use in this tutorial are located unter the Rubberduck > Unit Tests menu: 3. Create a function to test In the previous step, we started Excel and opened Visual Basic Editor. In this step, you are going to insert a new code module, and add a new Function to it.
VarPtr
is what's artificially complicating that test, introducing frail and flawed pointer logic that doesn't need to be there.
Change your stub data service to return some non-empty data - literally anything will do:
Option Explicit
Implements IDataService
'@Folder "Services.Stubs"
Private Function IDataService_GetSomeTable() As Variant
IDataService_GetSomeTable = GetSomeTable
End Function
Public Function GetSomeTable() As Variant
Dim result(1 To 50, 1 To 10) As Variant
result(1, 1) = "test"
GetSomeTable = result
End Function
Now change the stub worksheet service to keep a copy of the actual data (rather than just a LongPtr
):
Option Explicit
Implements IWorksheetService
'@Folder "Services.Stubs"
Private Type TStub
WasWritten As Boolean
WrittenData As Variant
End Type
Private this As TStub
Private Sub IWorksheetService_WriteAllData(ByRef data As Variant)
this.WasWritten = True
this.WrittenData = data
End Sub
Public Property Get DataWasWritten() As Boolean
DataWasWritten = this.WasWritten
End Property
Public Property Get WrittenData() As Variant
WrittenData = this.WrittenData
End Property
Now change the test to assert that IDataService.GetSomeTable
is returning the same data that IWorksheetService.WriteAllData
works with - you can do that using Assert.SequenceEquals
, which compares all elements of two arrays and fails if anything is different:
'@TestMethod
Public Sub WorksheetServiceWorksOffDataFromDataService()
'Arrange
Dim dataServiceStub As StubDataService
Set dataServiceStub = New StubDataService
Dim expected As Variant
expected = dataServiceStub.GetSomeTable
Dim wsServiceStub As StubWorksheetService
Set wsServiceStub = New StubWorksheetService
'Act
With New Macro
.Run dataServiceStub, wsServiceStub
End With
Dim actual As Variant
actual = wsServiceStub.WrittenData
'Assert
Assert.SequenceEquals expected, actual
End Sub
This makes the test much simpler, and it passes:
I will be updating the article with this simpler test later today.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With