chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Is there an easy way to verify that all faked methods was actually called?

Using code like this seems like a lot of work:
    Using AssertCalls.HappenedWithAnyArguments
        fakeProduct.ModifyPrice(0)
    End Using


I would be great if something like this was supported (without writing all the methods I have faked again):

IsolateVB.Verify.AllFakedMethodsWasCalledWithAnyArguments


This method should check that all my faked methods were called in the same order as my test code specify.

Here is my code:

  Public Sub SaveSiteToVP2009Test()

    ' Arrange
    ' -------
    Dim siteManager As New SiteManager()
    Dim fakeDB = FakeInstance(Of DataAccessAdapter)()

    ' Create input data
    Dim stagingSites As New EntityCollection(Of Staging_SiteEntity)
    stagingSites.Add(CreateInputStagingSites(100, 150, "Name1"))  ' Not changed
    stagingSites.Add(CreateInputStagingSites(101, 151, "Name2"))  ' Changed
    stagingSites.Add(CreateInputStagingSites(102, 153, "Name3"))  ' New

    ' Faking 3rd party API calls.
    ' First loop
    Using TheseCalls.WillReturn(1)
      fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
    End Using
    Using TheseCalls.WillBeReplacedWith(AddressOf FakeFetchEntityCollectionTest1Loop1)
      fakeDB.FetchEntityCollection(Nothing, Nothing)
    End Using
    Using TheseCalls.WillBeIgnored
      fakeDB.SaveEntityCollection(Nothing, False, False)
    End Using
    ' 2rd loop
    Using TheseCalls.WillReturn(1)
      fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
    End Using
    Using TheseCalls.WillBeReplacedWith(AddressOf FakeFetchEntityCollectionTest1Loop2)
      fakeDB.FetchEntityCollection(Nothing, Nothing)
    End Using
    Using TheseCalls.WillBeIgnored
      fakeDB.SaveEntityCollection(Nothing, False, False)
    End Using
    ' 3rd loop
    Using TheseCalls.WillReturn(0)
      fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
    End Using
    Using TheseCalls.WillBeIgnored
      fakeDB.SaveEntityCollection(Nothing, False, False)
    End Using

    ' Act
    ' ---
    Dim actual = siteManager.SaveToVP2009(fakeDB, stagingSites)

    ' Assert
    ' ------
    Assert.AreEqual(2, actual.Count)
    ' How to: Verify that faked methods was called ???

  End Sub
asked by Mikael (1.2k points)

2 Answers

0 votes
Hi Mikael,

There is no way to check if all of the faked methods were called, in fact it can cause a fragile test that would stop to work on every change to the code.

Perhaps you need to define exactly what ware you trying to test. Looking at your code I see you have a lot of setting up (Arrange) and has a single assert in the end of the test. It's a bit hard to understand exactly what you're trying to test.


Both TheseCalls and AssertCalls are not order specific and can set expectation or assertions on several methods at the same time (unless you use our repeat functionality) so you can write the first part of your test like this:
'...
        Using TheseCalls.WillReturn(0)
            fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
        End Using
        Using TheseCalls.WillReturn(1)
            fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
            fakeDB.GetScalar(Nothing, Nothing, AggregateFunction.CountRow, Nothing)
        End Using
        Using TheseCalls.WillBeReplacedWith(AddressOf FakeFetchEntityCollectionTest1Loop1)
            fakeDB.FetchEntityCollection(Nothing, Nothing)
        End Using
        Using TheseCalls.WillBeIgnored
            fakeDB.SaveEntityCollection(Nothing, False, False)
            fakeDB.SaveEntityCollection(Nothing, False, False)
            fakeDB.SaveEntityCollection(Nothing, False, False)
        End Using
        Using TheseCalls.WillBeReplacedWith(AddressOf FakeFetchEntityCollectionTest1Loop2)
            fakeDB.FetchEntityCollection(Nothing, Nothing)
        End Using
'...


SO you can write the assertion the same way (although I wouldn't recommand it):
'...
Using AssertCalls.HappenedWithAnyArguments
        fakeProduct.ModifyPrice(0)
        fakeDB.FetchEntityCollection(Nothing, Nothing)
'...
End Using
'...


Keep in mind that the order is not checked or used.
answered by dhelper (11.9k points)
0 votes
Hi dhelper, thanks for your reply.

There is no way to check if all of the faked methods were called..


Ok, so there are no easy ways. I just want to be sure that I did not overlook something in the documentations.

You are right. My test is a bit complex. The method that I am testing is calling up to 3 methods for each item in the collection that the method gets via its parameter.

There is no way to check if all of the faked methods were called, in fact it can cause a fragile test that would stop to work on every change to the code.


I do not see it as fragile, but tightly coupled. The code and its unit test are IMHO by nature very coupled. When you fake method calls done by the code you are testing, you need to know exactly what the code does.

Image this:
1. You write a method that calls the database (saves some data). You mock that call in your unit test so your unit test is not depended on a database.
2. Later someone makes a little change to the method, by replacing the call to the database with another call to the database (another method).
3. My faked methds is not called anymore and the unit test is still green.

BUT: Now we have a unit test that is “out of sync” with the code. The unit test is now cluttered with code that is never needed, and the unit test now depends on the database (it actually saves data to the database!).

If there was some easy way to verify that all my faked methods was actually called, then the unit test will more likely turn red in step 3 and we will know that a fix is needed. I find that to be a good thing!

(The fix will of cause be to ensure that unit test again is in sync with the code.)

Any opinions on my view of things are most welcome…

... just one small thing:

Both TheseCalls and AssertCalls are not order specific...


Ok. I understand this and your are right. But just to clearify. In some cases the order is relevant. Consider this code:

    Using TheseCalls.WillReturn(1)
      fake.DoSomething()
    End Using
    Using TheseCalls.WillReturn(2)
      fake.DoSomething()
    End Using


The first time DoSometing is called it will return 1 and the second time (and onwards) it will return 2.
answered by Mikael (1.2k points)
...