tags:

views:

23

answers:

1

Hello all, I'm trying to get my head around the idea of testing functionality and minimizing the number of asserts.

So lets say I have such a service method:

public void TransferFunds(int debitedId, int creditedId, Sum funds)
{
    Account debited = accountRepository.Get(debitedId);
    Account credited = accountRepository.Get(creditedId);
    debited.Debit(Sum);
    credited.Credit(Sum);
    accountRepository.Update(debited);
    accountRepository.Update(credited);
}

My unit tests I presume should then split into two, testing the crediting of one account and the debiting of the other. But should I assert on each account current state, to verify the sum has been added/deducted- or is this a test for my Account model? If so, what should I assert? that update was called? That doesn't verify the functionality...

Anyone has an idea?

+1  A: 

If you test the outcome (i.e. the final balances) then you are effectively also testing the Account objects, which are not under test here, so you should try and avoid that if possible.

In this scenario, I would expect Account to be an interface which you could mock out. I'm not sure what language you are using (looks like maybe C#). In Java, I would do this with an interface and jMock.

Then, you assert that the TransferFunds method calls Debit with the right Sum on the right Account, and calls Credit with the right Sum on the right Account. You will also need to mock out your account repository and have your mock framework return your mock Accounts in response to AccountRepository.Get

dty
Danny-Thanks for the prompt reply!So the way you see it there will be only 2 asserts:debited.AssertWasCalled(x=>x.Debit(sum));credited.AssertWasCalled(x=>x.Credit(sum));No asserts on the accountRepository (accountRepository.AssertWasCalled(r=>r.Update(credited)); or for the debited for that matter)Yeah, that makes sense :)thanks!
nieve
As I said, I'm not familiar with the language or framework you're using, but in Java/jMock, I would do the following:* Make two mock Accounts* Make a mock AccountRepository* "Allow" the AccountRepository to return the Accounts when requested with the correct IDs (I wouldn't "require" this because it's not the functionality we're trying to test)* Assert that the Debit method is called on the first Account with the right Sum* Assert that the Credit method is called on the second Account with the right Sum
dty