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
However if reflective mocks used it works. I'm new to TypeMock and had evaluation version installed. I don't know whether it's because evaluation version doesn't support natural mocks(not expired yet) or my code that's listed as follows is not right. Basically, i set up a mock method call which pass in an initialized object and return another initialized object. However, i got strange behaviors, like "Transactions[0].groupID is not set, use recorder.return()", but it's been setup. I'm wondering whether " the recorder will mock everything inside using block" cause my pass-in and return object has incorrect behavior. If i implemented in reflective mocks, it works fine.Any ideas? Thanks!

public void GetRecordsToSendTest1()
{
NBSInterfaceQueue target = new NBSInterfaceQueue();



using (RecordExpectations record = RecorderManager.StartRecording())
{
//all the method calls will be mocked
//initializtion
Business Object
ApprovedTransactionCollectionDO transactions = new ApprovedTransactionCollectionDO(ds);
Business Object
FinancialTransactionDO fs = new FinancialTransactionDO();
//GroupID is a property of fs object
//set up expectations
TransactionDALC.GetRelatedFinancialTransactionByGroupID(transactions[0].GroupID);
record.Return(fs);
fs.GroupID = transactions[1].GroupID;

}
asked by kosten (640 points)

3 Answers

0 votes
basically you are right.
inside a recording block ALL method calls will be mocked including those used as passed argument.
Specifically the statement:

Transactions[0].groupID

Is also recorded (there is a call to the indexer method.) and expects a return value. the thing is that in the order of execution of the entire line
that call is executed first and only then the outer method is called.
and since the record.Return comes only later we are missing the return value of that statement.

:!: also the usage of objects created inside the recording block as return values is incorrect (record.Return(fs); ). This object will be descoped when the block ends. although it will pass compilation it will result in unexcpected behaviour.

:!: the last statement in the block:fs.GroupID = transactions[1].GroupID;
is also missing a return value.

If you can post the entire code for the test ill try to make some order in it.
Hope this helps,
answered by lior (13.2k points)
0 votes
Thanks a lot, Lior. You make me more clear about the recorder's usage. I'm just wondering there is a easy way to handle the indexer of collection object? one solution is to move all these indexer out the using scope and passed in assigned variable instead. However, it's not natural.

basically you are right.
inside a recording block ALL method calls will be mocked including those used as passed argument.
Specifically the statement:

Transactions[0].groupID

Is also recorded (there is a call to the indexer method.) and expects a return value. the thing is that in the order of execution of the entire line
that call is executed first and only then the outer method is called.
and since the record.Return comes only later we are missing the return value of that statement.

:!: also the usage of objects created inside the recording block as return values is incorrect (record.Return(fs); ). This object will be descoped when the block ends. although it will pass compilation it will result in unexcpected behaviour.

:!: the last statement in the block:fs.GroupID = transactions[1].GroupID;
is also missing a return value.

If you can post the entire code for the test ill try to make some order in it.
Hope this helps,
answered by kosten (640 points)
0 votes
Thats really depends on you "real" code and what exactly do you intend to test.
Generally speaking indexers are method calls like any other calls. if you intend to mock them you can just do:
int dummy = transactions[0].GroupID;
record.Return(7); //you can replace 7 by the needed value/variable


However I believe that this is not what you intended.
The real trick here is that the actual passed parameters are not important (unless you want to tweak specific mocking based on passed value - what we call conditional mocking). If you just want to mock the call to
"TransactionDALC.GetRelatedFinancialTransactionByGroupID" and want that it will return "fs" you can just put it like:
...
TransactionDALC.GetRelatedFinancialTransactionByGroupID(0);
record.Return(fs); 
...
answered by lior (13.2k points)
...