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
Hello,

i want to do the following:

I have a List-Collection of Objects i want to mock. Because these Mocks have to return different ReturnValues and i don`t want my test to depent on the used algorithm in the method, i have to use MockObjects.

I create the list via a delegate like this:

List<OrderLine> myList = new List<OrderLine>();

ListEntryCreatorDelegate myListEntryCreator = delegate(int returnValue)
{
                // mocking orderlines 
                MockObject mockedOL =   
                         MockManager.MockObject(typeof(OrderLine));                
                mockedOL.ExpectGet("OrderLineNumber", returnValue);
                OrderLine myOrderLine = (OrderLine)mockedOL.Object;

                return myOrderLine;
};

for (int x = 1; x < listSize; x++)
{
                myList.Add(myListEntryCreator(x));
}


The list is returned by a type i am mocking and therefore i seem to have no chance to replace it by a own type i could mock. This forces me to use this way.

I want to make an assert, that only on one of the listmembers a get is made. If i just make an expectation on the expected one and the test fails, the error message should be easy to understand and not complaining about missing references. Is it somehow possible to make "anti-expectations"?

Using counters is not possible on the casted MockObjects in the list. How would your approach look?

Thanks in advance!
asked by Kelloggs (1.3k points)

4 Answers

0 votes
Hi
I see here two options:
1. The cleaner option is use Isolator Arrange Act Assert API
than you can do this:
// Notice how the delegate got shorter!
ListEntryCreatorDelegate myListEntryCreator = delegate(int returnValue)
{
    OrderLine fake = Isolate.Fake.Instance<OrderLine>();
    Isolate.WhenCalled(()=> fake.OrderLineNumber).WillReturn(returnValu
    return fake;
};

// ... 
// here is the list that you built in the delegate 
List<OrderLine> mockedOrderLine = SomeClass.SomeMethod();

// call to OrderLineNumber from some index in the mockedOrderLine 
//..
//Here you verify only for OrderLine that is in index 1 OrderLineNumber was called
Isolate.Verify.WasCalledWithAnyArguments(()=> mockedOrderLine[1].OrderLineNumber);


2. If for some reason you can't use the new API you can use the following
solution:
The MockObject class has its own Verify method method which will do verification only on the instance it controls.
The problem here is the MockObjects are created inside the delegate and are not saved.
If you will save the MockObjects in a different list you can use it to verify
that only specific index index was called:
List<MockObject> mockList = new List<MockObject>();
//...

ListEntryCreatorDelegate myListEntryCreator = delegate(int returnValue)
{
    MockObject mockedOL =
             MockManager.MockObject(typeof(OrderLine));
    mockedOL.ExpectGet("OrderLineNumber", returnValue);
    OrderLine myOrderLine = (OrderLine)mockedOL.Object;

    //save the MockObject
    mockList.Add(mockedOL);
    return myOrderLine;
};

// ...

// here is the list that you built in the delegate
List<OrderLine> mockedOrderLine = SomeClass.SomeMethod();

// call to OrderLineNumber from some index in the mockedOrderLine
//.. 

//Use the MockObject list to Verify only on index 1 that OrderLineNumber was called
mockList[1].Verify();


:idea: you can save only the MockObject that you want to make the verification on if you know what index it will be when the delegate is called.
answered by ohad (35.5k points)
0 votes
Hi ohad,

i have been such a blockhead. Of course, thats the way! I should have seen that!

Thank you very much!
answered by Kelloggs (1.3k points)
0 votes
Hi
Actually there is a cleaner way too do it Reflective mocks.
Use MockManager.GetMockOf method

MockManager.GetMockOf allows you to get the the mock controller of a specific instance.
So you don't have to save the list of MockObject.
Instead you can do this:
//Verify only on index 1 that OrderLineNumber was called 
MockManager.GetMockOf(mockList[1]).Verify();
answered by ohad (35.5k points)
0 votes
That's even better! Now it is good readable and looks clean. Thank you!
answered by Kelloggs (1.3k points)
...