Rubberduck
Rubberduck copied to clipboard
Running a unit test which fakes both MsgBox.Returns and InputBox.Returns fails
Rubberduck version information
Rubberduck version 2.5.2.5906 loading:
Operating System: Microsoft Windows NT 10.0.19042.0 x64
Host Product: Microsoft Office x86
Host Version: 16.0.14827.20158
Host Executable: EXCEL.EXE;
Description Running a unit test which fakes both MsgBox.Returns and InputBox.Returns fails with "Running a test method failed with an exception".
To Reproduce Steps to reproduce the behavior:
- Create the following procedure
Sub TafelVanVermenigvuldiging()
Dim intGetal As Integer, intTeller As Integer
intGetal = InputBox("Geef een getal:")
If intGetal < 1 Or intGetal > 100 Then
MsgBox "Het getal moet tussen 1 en 100 liggen."
Else
For intTeller = 0 To 9
MsgBox (intTeller & "x" & intGetal & "=" & intTeller * intGetal)
Next
End If
End Sub
- Add the following test module
Option Explicit
Option Private Module
'@TestModule
'@Folder("Tests")
Private Assert As Object
Private Fakes As Object
'@ModuleInitialize
Private Sub ModuleInitialize()
'this method runs once per module.
Set Assert = CreateObject("Rubberduck.AssertClass")
Set Fakes = CreateObject("Rubberduck.FakesProvider")
End Sub
'@ModuleCleanup
Private Sub ModuleCleanup()
'this method runs once per module.
Set Assert = Nothing
Set Fakes = Nothing
End Sub
'@TestInitialize
Private Sub TestInitialize()
'This method runs before every test in the module..
End Sub
'@TestCleanup
Private Sub TestCleanup()
'this method runs after every test in the module.
End Sub
'@TestMethod("TafelVanVermenigvuldigingen")
Private Sub TafelVanVermenigvulgingenVan20()
On Error GoTo TestFail
Fakes.InputBox.Returns 20
Fakes.MsgBox.Returns 20 'if this line or the one above is commented, it works, but you manually need to return the messageboxes or enter a value
TafelVanVermenigvuldiging
With Fakes.MsgBox.Verify
.Parameter "prompt", "0x20=0", 1
.Parameter "prompt", "1x20=20", 2
.Parameter "prompt", "2x20=40", 3
.Parameter "prompt", "3x20=60", 4
.Parameter "prompt", "4x20=80", 5
.Parameter "prompt", "5x20=100", 6
.Parameter "prompt", "6x20=120", 7
.Parameter "prompt", "7x20=140", 8
.Parameter "prompt", "8x20=160", 9
.Parameter "prompt", "9x20=180", 10
.Exactly 10
End With
TestExit:
Exit Sub
TestFail:
Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
Resume TestExit
End Sub
Expected behavior The test runs (and passes).
Logfile
2022-02-08 17:39:16.2080;TRACE-2.5.2.5906;Rubberduck.Common.LogLevelHelper;
Rubberduck version 2.5.2.5906 loading:
Operating System: Microsoft Windows NT 10.0.19042.0 x64
Host Product: Microsoft Office x86
Host Version: 16.0.14827.20158
Host Executable: EXCEL.EXE;
2022-02-08 17:39:19.6973;INFO-2.5.2.5906;Rubberduck.Parsing.VBA.RubberduckParserState;RubberduckParserState (555) is invoking StateChanged (Busy);
2022-02-08 17:39:19.7033;TRACE-2.5.2.5906;Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase;CancellationTokenSource was already disposed for OnParserStateChanged.;
2022-02-08 17:39:19.8713;ERROR-2.5.2.5906;Rubberduck.UnitTesting.TestEngine;Unexpected exceptino while running test method.;System.InvalidCastException: Specified cast is not valid.
at Rubberduck.UnitTesting.Fakes.MsgBox.MsgBoxCallback(IntPtr prompt, Int32 buttons, IntPtr title, IntPtr helpfile, IntPtr context) in C:\projects\rubberduck\Rubberduck.Main\ComClientLibrary\UnitTesting\Fakes\MsgBox.cs:line 49
at Rubberduck.VBEditor.ComManagement.TypeLibs.Abstract.IDispatch.Invoke(Int32 dispIdMember, Guid& riid, UInt32 lcid, UInt32 dwFlags, DISPPARAMS& pDispParams, Object& pVarResult, EXCEPINFO& pExcepInfo, UInt32& pArgErr)
at Rubberduck.VBEditor.ComManagement.TypeLibs.Unmanaged.IDispatchHelper.Invoke(IDispatch obj, Int32 memberId, InvokeKind invokeKind, Object[] args) in C:\projects\rubberduck\Rubberduck.VBEEditor\ComManagement\TypeLibs\Unmanaged\IDispatchHelper.cs:line 121
at Rubberduck.VBEditor.ComManagement.TypeLibs.TypeInfoVBEExtensions.StdModExecute(String name, Object[] args) in C:\projects\rubberduck\Rubberduck.VBEEditor\ComManagement\TypeLibs\TypeInfoVBEExtensions.cs:line 155
at Rubberduck.VBEditor.ComManagement.TypeLibs.VBETypeLibsAPI.ExecuteCode(ITypeLibWrapper projectTypeLib, String standardModuleName, String procName, Object[] args) in C:\projects\rubberduck\Rubberduck.VBEEditor\ComManagement\TypeLibs\Public\TypeLibsAPI.cs:line 261
at Rubberduck.UnitTesting.VBEInteraction.RunTestMethod(ITypeLibWrapper typeLib, TestMethod test, EventHandler`1 assertCompletionHandler, Int64& duration) in C:\projects\rubberduck\Rubberduck.UnitTesting\UnitTesting\VBEInteraction.cs:line 55
at Rubberduck.UnitTesting.TestEngine.RunTestMethod(ITypeLibWrapper typeLib, TestMethod test) in C:\projects\rubberduck\Rubberduck.UnitTesting\UnitTesting\TestEngine.cs:line 385
2022-02-08 17:39:20.2352;INFO-2.5.2.5906;Rubberduck.Parsing.VBA.RubberduckParserState;RubberduckParserState (556) is invoking StateChanged (Ready);
2022-02-08 17:39:20.2352;TRACE-2.5.2.5906;Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase;CancellationTokenSource was already disposed for OnParserStateChanged.;
Side note, the "Unexpected exceptino" typo should be fixed together with this issue.
Changing the order of the fakes seems to work:
Fakes.MsgBox.Returns 20
Fakes.InputBox.Returns 20
More generally, you need to set the MsgBox first to to all values that you want the Inputbox to have. The following does not work:
Fakes.InputBox.Returns 1000, 1
Fakes.InputBox.Returns 2000, 2
Fakes.InputBox.Returns 300, 3
Fakes.InputBox.Returns 4000, 4
Fakes.InputBox.Returns 500, 5
Fakes.MsgBox.Returns 1
but this does:
Fakes.MsgBox.Returns 1000, 1
Fakes.MsgBox.Returns 2000, 2
Fakes.MsgBox.Returns 300, 3
Fakes.MsgBox.Returns 4000, 4
Fakes.MsgBox.Returns 500, 5
Fakes.MsgBox.Returns 1, 6
Fakes.InputBox.Returns 1000, 1
Fakes.InputBox.Returns 2000, 2
Fakes.InputBox.Returns 300, 3
Fakes.InputBox.Returns 4000, 4
Fakes.InputBox.Returns 500, 5