Antes de responder a esa pregunta, debe decidir qué es lo que realmente quiere lograr.
Tú escribes el código. Espera que cumpla con su contrato (en otras palabras, hace lo que se supone que debe hacer. Escribir lo que se supone que debe hacer es un gran paso adelante para algunas personas).
Para estar razonablemente convencido de que el código hace lo que se supone que debe hacer, puede mirarlo lo suficiente o escribir un código de prueba que pruebe suficientes casos para convencerlo de "si el código pasa todas estas pruebas, entonces es correcto".
A menudo solo le interesa la interfaz definida públicamente de algún código. Si uso la biblioteca, no me importa cómo lo hizo funcionar correctamente, sólo que hace el trabajo correctamente. Verifico que su biblioteca es correcta realizando pruebas unitarias.
Pero estás creando la biblioteca. Hacer que funcione correctamente puede ser difícil de lograr. Digamos que solo me importa que la biblioteca haga la operación X correctamente, así que tengo una prueba unitaria para X. Usted, el desarrollador responsable de crear la biblioteca, implementa X combinando los pasos A, B y C, que son totalmente no triviales. Para que su biblioteca funcione, agregue pruebas para verificar que A, B y C funcionen correctamente. Quieres estas pruebas. Decir "no deberías tener pruebas unitarias para métodos privados" no tiene sentido. Usted desea que las pruebas para estos métodos privados. Tal vez alguien le diga que la unidad que prueba métodos privados está mal. Pero eso solo significa que no puede llamarlos "pruebas unitarias" sino "pruebas privadas" o como quiera llamarlas.
El lenguaje Swift resuelve el problema de que no desea exponer A, B, C como métodos públicos simplemente porque desea probarlo dando a las funciones un atributo "comprobable". El compilador permite que se invoquen métodos privados comprobables desde pruebas unitarias, pero no desde código que no sea de prueba.