简体   繁体   中英

Effective Java Item 13 and TDD

I just googled "Joshua Bloch TDD"... not much came up, which is a huge shame because I'd really like to know what he's got to say on the matter.

Item 13 (I'm looking at the 2nd edition) is entitled "Minimize the accessibility of classes and members". After a couple of pages he says:

To facilitate testing, you may be tempted to make a class, interface or member* more accessible. ... It is acceptable to make a private member of a public class package-private in order to test it, but it is not acceptable to raise the accessibility any higher than that... Luckily, it isn't necessary either, as tests can be made to run as part of the package being tested, thus gaining access to its package-private elements.

* by "members" he means "fields, methods, nested classes and nested interfaces".

As a TDD newb, but gradually finding my feet, I am aware that the current consensus seems to be not to include testing classes with the app code packages, nor even to have a matching structure under src\\test and src\\main: mostly TDD experts readily seem to structure their testing directories in other ways (eg you have one directory called "unittests" another called "functionaltests" and another called "e2etests").

Specifically, I have followed the TDD development of the auction app in "Growing Object Oriented Software Guided by Tests". The author there has no qualms about adding hundreds of public methods. Furthermore, after one chapter I looked at the downloaded "structure so far" and he had completely changed the testing directory structure to divide things into categories of test...

Is there any seasoned TDD hand out there who has, at least in the past, found this to be a source of dilemma? If so, how have you resolved it?

As a practical example, I'm cutting my teeth on TDD techniques by developing a Lucene index app: it indexes documents and then lets you query them. At the current time all the app classes are in the same package. The only method which actually needs to be public is main in one class. And yet, of course, I have many, many public methods: they could all be package-private were it not for the fact that I am using TDD.

PS no tag for "method-visibility" so I chose "class-visibility"

later

It appears that I may have been led down a rather unfortunate path by the approach taken in "Growing Object-Oriented...", where the over-use of public methods was presumably used just because it's a demonstration of the technique. Ha.

If you want to split your categories of tests, does anyone ever use this sort of approach:

\\src\\unit_tests\\java\\core\\MainTest.java

but also, for example:
\\src\\func_tests\\java\\core\\MainTest.java
and
\\src\\e2e_tests\\java\\core\\MainTest.java ?

as tests can be made to run as part of the package being tested

This does not mean that you have to put your tests in the same directory as main classes, they just have to be in the same package which can very well be separate directory.

Assume you have a package com.acme.foo . So your directory structure may be:

src
  main
    java
      com
        acme
          foo
            MainClass
  test
    java
      com
        acme
          foo
            MainClassTest

MainClassTest is in the same package as MainClass so it has access to package-private stuff. But these are separate directories, so your resulting JAR will not contain MainClassTest .

I am not sure how this works in Gradle, as I am using Maven, but I imagine the concepts there are similar. Therefore I will explain it with Maven in mind. The typical setup in a Maven project looks like this:

在此处输入图片说明

On the root level of the projects there is src and target . Into the target folder everything goes that is created during the build process. This means that src contains the sources of our actual project. Under src there are two other directories: main and test . Simply put into main goes everything that will end up in the productive code, that will be delivered. The test directory contains the test code for the main tree.

Therefore it is usual that the same package hierarchy from the src/main/java directory is also present in src/test/java and therefore for a test class with the same package definition will have access to all members of the producive class which resides in the main branch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM