4

Let assume I have two simple model classes: Product and Brand

It is obvious I have a query method in Product class like this

Product product = Product.findById(123);

What if, I want to query products by brand?

ArrayList<Product> products = Product.findByBrand(234);
// or
ArrayList<Product> products = Product.findByBrand(new Brand("ABC", 234));

Assume 234 is the brand ID in the database.

I assume the 2nd way of writing make the method more easy to test as I can mock the Brand class in my unit test, right?

Ixrec
  • 27,621
  • 15
  • 80
  • 87
Yoga
  • 325
  • 1
  • 3
  • 9

2 Answers2

5

For unit-testing the findByBrand method, there is no real difference between passing in a Brand object or just an ID.

The difference is more relevant for the code calling findByBrand.
In the large majority of cases, that code should already be dealing with Brand objects, so passing that as an argument to findByBrand makes the most sense.

The only reason for findByBrand to accept a plain ID would be if (nearly) all current and expected callers are already naturally working with Brand-IDs without having corresponding Brand objects.

Bart van Ingen Schenau
  • 71,712
  • 20
  • 110
  • 179
  • Notice that "... if (nearly) all callers are already naturally working with Brand-IDs ..." might occur inside the library code (i.e. other model classes), whereas application code might prefer to use `Brand` objects exclusively for safety and ease-of-you. In that case, it might make sense to use visibility. – rwong May 23 '15 at 11:35
  • @rwong: You are right. It it likely that application code will use/prefer `Brand` objects. – Bart van Ingen Schenau May 23 '15 at 17:28
1

It's more than just whether you can mock a Brand object or not.

First, I'll assume your Product is really a Data Access Object, and not a simple Java Bean/DTO/POJO.

The real question to ask is, how long will this assertion hold?

Assume 234 is the brand id of the brand in database.

Will simple int values become long in the future, necessitating all methods interacting with a 'brand ID' to be changed from accepting an int to long? Will it become an alphanumeric, which might be possible to remain as an int (plausibly - if we're talking hexadecimals smaller than Integer.MAX_VALUE, and there is now a conversion method/utility somewhere to turn "AA" into 170) or will the whole type-changing parade enter the String phase?

The one slim benefit I can see for accepting an int is that you don't have to pay particular attention to a null input. Well, there's still the extremely odd chance of a null explicitly casted as an Integer and then getting auto-boxed, but you probably have other concerns then.

h.j.k.
  • 1,737
  • 1
  • 16
  • 20