Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm about to write a lot of test for my application. While some of the tests check whether everything works if the user enters the right data, most of them deal with wrong/missing data. In these cases nothing should be updated and an exception should be thrown.

At the moment, this leads to a lot of duplicated code, because every test has to make sure that not only the exception is thrown but that no data in my (mocked in-memory) database is changed.

My first idea was to move these tests into a function and to call this function in every test. Pro: I still can use very explicit tests. Contra: I have to remember changing the function and adding more tests whenever I add more functionality to the checked function.

But I could as well add a property to my mocked in-memory-repository that indicates whether an entity was updated. Pro: I'll never have to worry about a forgotten check. Contra: The check is quite vague - When it fails I'll only knew that something was changed. In order to find the error I'll have to debug step by step through the function.

What is the better approach? Maybe there's an even better third solution?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Are you sure that you're actually talking about a Mock and not a Stub (or a fake)?

Mocks don't have "flags" - you configure them to behave however you want them to, so if there was in fact a flag then that flag would also be mocked and therefore be meaningless to the test.

You use Mocks to verify interactions with a dependent component. In the case of a repository, you should only have to verify that a particular update method was not called, which in all mocking frameworks I know of is just one line of code.

The fact that repositories are so trivially easy to mock and verify is one of the main (only?) reasons to use them in the first place.

If the verification line is long e.g. due to a method having a lot of parameters or something then sure, refactor it to a common test method. If it really starts to get messy then you can create a fluent test builder that abstracts the most common steps and verifications, so that your tests look like a sort of DSL. But when I say "messy" I'm talking about literally hundreds of these tests; less than a dozen and it's definitely not worth the bother or the added complexity.

Keep in mind that unit tests are specifications and are supposed to tell you in very simple terms how the code actually behaves. While it's important to keep test code clean and periodically refactor, it's also important not to overdo it and end up creating test code that's just as complex as the SUT.

I don't know exactly what your specs are, but if they include something like "should not update entity X with ID Y" then that's exactly what the test code should look like as well, and a Mock is the most appropriate tool. On the other hand, if your specs talk about the end state of the data (e.g. "entity X should still status Y and not Z") then a Mock isn't a very good choice, you'll want to use an actual fake database - usually an in-memory database - and have your tests actually look up those entities and check them. In either case, I don't see what property you could add to the repository itself that would really help.

share|improve this answer
    
You're right, I misunderstood the meaning of "mocking" (I'm really new to the idea of writing automated tests). My repository is an in-memory-repository and implements the same interface as the real one. My idea was to add a new property "hasChanged". Whenever the in-memory-repository is asked to update/delete/insert something, this property is set to true. Then all I'd have to do is to check this property. If it's false, everything is alright because nothing was updated (as desired if the user enters wrong information). If it's true then there's a bug. –  Christopher Sep 7 '13 at 10:26
    
@Christopher: That's fine, it's a fairly typical use case of a stub, but if you're working in an environment that supports mocks, I think you'll find it a lot simpler, because instead of building in a lot of functionality to make it easier to check the end state, you can just verify that the unit being tested attempted to perform some data operation, which is what really matters most of the time. Save the in-memory database for component tests and integration tests, if you can. –  Aaronaught Sep 7 '13 at 16:12
    
Ok, that sounds logical. I'll definitely give mocks a try, thank you! –  Christopher Sep 8 '13 at 12:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.