Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Could someone explain: "Be Defensive - They're out to Get Your Code! - Defensively assert about the state of parameters passed in methods, constructors, and mid-method."?

which, desarcastified, I take to mean:

"Don't defensively assert about the state of parameters passed in methods, constructors, and mid-method."

Specifically:

"You see, there are testing freaks out there that like to instantiate your object, or call a method under test and pass in nulls"

Isn't it the case that a calling a method with (say) null parameters where they are supposed to be non-null should raise an exception? Isn't an assertion failure reasonable in this case?

I understood and agreed with a lot of the other stuff (although it struck me as a bit dogmatic) but this one I don't get.



I think what the author is getting at is testing a particular method on an object without having to mock up all the data required by the entire object. I guess?

Agreed that the whole article would be more useful without the sarcasm.


So that's basically allowing operations on a half-broken object, just so that you can test it without creating all the dependencies?... I see how it might be useful, but I just can't agree with that.

The tests are not the goal - a working product is. That's just making a trade-off between less lines in a test -vs- code that doesn't explode mid-transaction when that null suddenly occurs in a real-world scenario. If I'm supposed to write my code properly, testies should not be too lazy while writing the tests.


It's no longer a unit-test once you're putting the object into the living system. It becomes a system test and then you might as well test the whole system instead of faking things with mockups.


If you use Java, EasyMock makes this a non-issue.

I have found that with a test framework like EasyMock, you no longer have to jump through so many of these goofy tdd hoops. You can mock methods, return values, thrown exceptions, parameters to methods to another object inside a method, etc. It still doesn't warrant writing crap code using anti-patterns, but nevertheless, it makes life more bearable by putting the focus back on the logic at hand and less on trying to follow the tdd mantra of design.


I interpret this to mean two things:

1. If you are going to assert these things, don't do it in the middle of the method - do it in a place that makes sense (start of the method).

2. One of the members of my team likes to make assertions about parameters that aren't actually valid but just sound like they are, for example, wrapping the entire code in a method with an int id parameter with a

  if (id > 0) { 
     ...
  }
block so that the method silently does nothing if you pass in a negative number. Except of course that there's nothing in our domain model to say that IDs can't wrap zero into negative space or that this isn't a valid scenario.

So in other words, having a bunch of unnecessary assertions that spring up in seemingly random places makes your code hard to test.


> 1. If you are going to assert these things, don't do it in the middle of the method - do it in a place that makes sense (start of the method).

Sure, I can see that -- assertions in the middle of a method might well indicate that maybe that bit should be split into more than one method.

But the article goes further than that: they seem to complain about assertions guarding parameter values. I really don't get that. Actually, I'll go one further: complaining about that is unjustifiable.

Anyway, I also don't always get the particular flavour of OOP dogma that Java devs sometimes seem to promote. It certainly feels different to me from Python world, and I suppose it is.

When I see the phrase "silently does nothing" I feel vaguely uneasy.


> Isn't it the case that a calling a method with (say) null parameters where they are supposed to be non-null should raise an exception?

Not really. Checking parameters in every method (especially an OO system) is a sure way to have poor performance. Null values as other kinds of testing should be done in the areas of the system that create and receive objects from outside.

Normal methods should just work find even if a parameter is NULL. Although this doesn't look nice, it is a way to make the system testable, in the absence of true NullObjects.


> Checking parameters in every method (especially an OO system) is a sure way to have poor performance.

This seems overly general to me. I'm not sure it's a "sure way to have poor performance." It seems to me that (for example) a null-check is pretty fast.

> Normal methods should just work find even if a parameter is NULL.

What's a "normal method"? And if the business logic of the method requires a particular parameter to be non-null (or has some other constraint), what should happen when a null parameter is passed-in (by a test or otherwise)?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: