简体   繁体   中英

TDD and mocking

First of all, I have to say, I'm new to mocking. So maybe I'm missing a point.

I'm also just starting to get used to the TDD approach.

So, in my actual project I'm working on a class in the business layer, while the data layer has yet to be deployed. I thought, this would be a good time to get started with mocking. I'm using Rhino Mocks, but I've come to the problem of needing to know the implementation details of a class before writing the class itself.

Rhino Mocks checks if alle the methods expected to be called are actually called. So I often need to know which mocked method is being called by the tested method first, even though they could be called in any order. Because of that I'm often writing complicated methods before I test them, because then I know already in which order the methods are being called.

simple example:

public void CreateAandB(bool arg1, bool arg2) {
    if(arg1)
        daoA.Create();
    else throw new exception;
    if(arg2)
        daoB.Create();
    else throw new exception;
}

if I want to test the error handling of this method, I'd have to know which method is being called first. But I don't want to be bugged about implementation details when writing the test first.

Am I missing something?

You have 2 choices. If the method should result in some change in your class the you can test the results of your method instead. So can you call CreateAandB(true,false) then then call some other method to see if the correct thing was created. In this situation your mock objects will probably be stubs which just provide some data.

If the doaA and doaB are objects which are injected into your class that actually create data in the DB or similar, which you can't verify the results of in the test, then you want to test the interaction with them, in which case you create the mocks and set the expectations, then call the method and verify that the expectations are met. In this situation your mock objects will be mocks and will verify the expected behaviour.

Yes you are testing implementation details, but your are testing the details of if your method is using its dependencies correctly, which is what you want to test, not how it is using them, which are the details you are not really interested in.

EDIT

IDao daoA = MockRepository.GenerateMock<IDao>(); //create mock
daoA.Expect(dao=>dao.Create); //set expectation

...

daoA.VerifyExpectations(); //check that the Create method was called

you can ensure that the expectations happen in a certain order, but not using the AAA syntax I believe ( source from 2009 , might have changed since, EDIT see here for an option which might work ), but it seems someone has developed an approach which might allow this here . I've never used that and can't verify it.

As for needing to know which method was called first so you can verify the exception you have a couple of choices:

  • Have a different message in your exception and check that to determine which exception was raised.
  • Expect a call to daoA in addition to expecting the exception. If you don't get the call to daoA then the test fails as the exception must have been the first one.

Often times you just need fake objects, not mocks. Mock objects are meant to test component interaction, and often you can avoid this by querying the state of SUT directly. Most practical uses of mocks are to test interaction with some external system (DB, file system, webservice, etc.), and for other things you should be able to query system state directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM