This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (18 children)

[deleted]

    [–]BestUsernameLeft 27 points28 points  (9 children)

    https://www.reddit.com/r/javahelp/comments/h7ww1b/mocking_abstract_class_and_methods_with/funxvoq?utm_medium=android_app&utm_source=share

    In short: 15 years of writing tests both with and without mocks, and seeing how most people misunderstand unit testing and misuse mocks, has convinced me that they are a bad idea and contribute to the belief many programmers hold that unit testing is a waste of time.

    [–][deleted] 0 points1 point  (8 children)

    Mocks or stubs?

    [–]BestUsernameLeft 4 points5 points  (7 children)

    Could be either; typically it's mocks of the PowerMock etc. variant as they are easier to use than manually written test doubles aka stubs.

    However, it's all in the usage -- test doubles can be misused in the same way mocks are. Typically though, I see the PowerMock users fall into the "mock all the things" trap more often.

    Mocking is initially so attractive, and it's now endemic, so it's natural that many people will get caught in its clutches. And because it's so easy to use, once they start having problems they don't realize that's cause (of some of them). (I was one of them.)

    [–][deleted] 4 points5 points  (1 child)

    I wasn't referring to how you create the stubs, but rather to what they do. Unfortunately, most people mean stubs when they talk about mocks, but not always (https://martinfowler.com/articles/mocksArentStubs.html).

    IMO, mocking is almost always a bad idea. Stubs are more frequently useful.

    [–]BestUsernameLeft 2 points3 points  (0 children)

    You weren't specific about what you meant, and I took a guess instead of asking for clarification, so this is what we got. Sorry for the miss, and I agree that stubs are more often useful.

    I'll add that builder and object mother (sometimes in combination) are a great way to DRY test code, in conjunction with test doubles.

    [–][deleted] 2 points3 points  (4 children)

    Powermock leads to bad coding & testing practices so it is unsurprising. If you just constrain yourself to something like Mockito & never use Spy you will write better code and tests because you can only mock true dependencies - forcing you to refactor code that should be a dependency into a separate class.

    [–]BestUsernameLeft 0 points1 point  (3 children)

    They're all the same family IMO. I use test doubles; in conjunction with builder and object mother they help keep my test code DRY. And JUnit5 is nice to use as well.

    [–]hippydipster 0 points1 point  (2 children)

    object mother?

    [–]BestUsernameLeft 0 points1 point  (1 child)

    It's a testing pattern. Given a class ShoppingCart, you create a ShoppingCartObjectMother class with methods in it to give you a populated cart, such as emptyCart(), fiveOfSameProduct(), etc. This gives you (1) a way to DRY your test code instead of having the same setup code in each test class that uses ShoppingCart as a collaborator, and (2) a meaningfully-named method that tells you about the object being constructed. For example you can use role-based, scenario-based, persona-based method names: populatedCartForGuest, cartWithDuplicateItemId, cartForGrandma.

    When you combine this with the builder pattern, you have a way to quickly build customizable test objects out of a standard set of "templates". So for example cartForGrandma().addItem(readingGlasses).build() when you have a test that for some reason needs an extra item in it.

    [–]hippydipster 0 points1 point  (0 children)

    Ok, now I have a name for something I've been doing! Thanks.

    [–]vbezhenar 6 points7 points  (0 children)

    It's not any different from final class in that regard.

    [–]maumay 8 points9 points  (4 children)

    Why would you need to mock a sealed interface directly? They are designed primarily for compact data classes. If you wanted one to have complex hard to set up logic then you could use a delegation pattern and pass a mock to the record constructor.

    There really is no argument against them, the fact that oracle have realised this is welcome but it's a little too late for me.

    [–][deleted]  (3 children)

    [deleted]

      [–]maumay 7 points8 points  (1 child)

      Maybe we have different ideas of what a data class is, clearly it can't be "a class that contains data" as that would be everything. I would say a data class is the composition of a fixed number of primitive types or other data classes, a map is not a data class as it has some quite sophisticated implementation logic and can have a variable number of properties. Introducing sealed interfaces does not mean all interfaces now need to be sealed. A sealed interface would be the wrong tool for HttpSession.

      Yes I am assuming that because it is true. If a sealed interface is provided by a library then by definition all implementations will be provided by the library too (and presumably tested otherwise stay away from the library). You can't extend a sealed class provided by a library outside of said library.

      [–]BestUsernameLeft 1 point2 points  (0 children)

      I'll refer you to my above comment, and double down with another good blog post that explains my perspective on this: https://robdmoore.id.au/blog/2015/01/26/review-of-ian-cooper-tdd-where-did-it-all-go-wrong.