← Back to Upcase

Should I test internal state of the object?

(Patrik Bóna) #1

Hello guys,

I do not test private methods. But what about internal state of the object?

I am working on a game. My object has public update method. When this method is called, then it calls several private methods. For example move method which should change position based on speed, heading and so.

Anyway coordinates are part of internal state.

On one hand, internal state probably should be not tested. On the other hand there are some calculations which I would like to have tested, but I do not not how (because it is done in private methods…).

Do you have any advice for me? Should I change my OO design somehow?

This is driving me crazy. I would like to write some code, but I am struggling with this… :wink:

Many thanks in advance for your replies.

(Pedro Moreira) #2

Just guessing here:

It may be your private methods are telling you they want to get promoted to public, maybe even into their own class where they can be more easily tested and organized.

Looking forward to reading other answers to this, as well.

(Ben Orenstein) #3

I’m with @pedromoreira here.

If you find yourself wishing you could test your private methods, you should promote those methods into their own object with public methods and test that.

Why don’t you give that a try and see how it feels?

(Jon Seidel) #4

Well… my question would be: why don’t you test your private methods… they’re code just like everything else?

(Ben Orenstein) #5

Because I said so!

Just kidding. Here’s a good discussion: http://blog.rubybestpractices.com/posts/gregory/034-issue-5-testing-antipatterns.html

(Pedro Moreira) #6

Sandi Metz has some thoughts on this has well: http://www.youtube.com/watch?v=URSWYvyc42M

(Jon Seidel) #7

:=) Thanks Ben/Pedro… got it!.

(Jon Seidel) #8

I gotta admit, @benorenstein, @pedromoreira… I’m still having a problem here, even after having read the references you provided.

Let’s say I have TDD’d my project down to the point where I know I need, say, a get_column_word method, and at this point, I also know that this really is an internal utility (i.e., private) method that should never be seen externally.

What I keep wanting to do is to write simple unit tests to drive out the code for that method, rather than having to keep testing the higher-level (caller) method and hoping that I’ve got that private method correct. Seems like I’m forced to work on the ‘outside’ without being allowed to go ‘inside’.

(Pedro Moreira) #9

@JESii, it seems that that method is really telling you it wants to be part of your public API.

You describe going along a route where you discover this method and find that you want to talk to it:
promote and see how that feels.

Also, I wouldn’t get very bogged down with it being hidden. Marking a method as private doesn’t mean it can’t get called, it just signals that it shouldn’t.

Hope this helps :slight_smile:

To balance my previous Sandi Metz reference, here’s another: “Marking a method as private doesn’t stop me from calling it. It is just a matter of how difficult you want to make it for me”.

I’m quoting ad-hoc from the Hashrocket Lunch n’ Learn series with Sandi, I think they’re worth a viewing: http://vimeo.com/48071436 and http://vimeo.com/48106365

(Jon Seidel) #10

Tnx, @pedromoreira . I know about ‘private’ being just a guideline. I have been trying to better organize my code and kept running into this problem. I can leave them all as public methods and test them… Just wasn’t sure that was the “best” approach.

As I recall, I’ve gotten feedback about needing to make more of my methods private. And it’s still a general question: given that Metz and others say: “don’t test private methods”, how do you TDD that potentially large section of code?

(Ben Orenstein) #11

Extract a new class and TDD that class’ public methods.