Reputation: 2110
I have read about TDD and I tried it on my new project.
I understand that in TDD it is like blackbox testing , ie it matters what rather than how.So, I concluded and stopped testing private methods after reading about it on many posts as it is not correct way.
However, I failed to do it due to these reasons.
I will show you by example : I have a program that reads a text paragraph so I wrote something like this in my test method (for tdd step1).
/*
My program reads a textual paragraph from file and saves it to my custom paragraph object;
*/
So accordingly I made this method to create the RED case.
public void paragraphMustNotBeNullTest(){
File f = new File("some path")
ParagraphReader reader= new ParagraphReader();
reader.read();
assertNotNull("my custom paragraph is null",reader.getCustomParagraph());
}
I have written following code:
package com.olabs.reader;
import java.io.FileInputStream;
import java.io.InputStream;
import com.olabs.models.OlabsParagraph;
public class Para {
private String paragraphText = null;
private Paragraph oParagraph = null;
public Paragraph getCustomParagraph() {
return oParagraph;
}
public void setoParagraph(Paragraph oParagraph) {
this.oParagraph = oParagraph;
}
public void read() {
InputStream is = new FileInputStream("abc......");
// ..
String text = is.read(); // assume I got text read from file.
this.paragraphText = text;
}
private void createCustomParagraph()
{
Paragraph p = new Paragraph();
p.setText(paragraphText);
p.setId(1);
p.setType("Story");
...........
}
private void countWords()
{
// counting words in paragraph logic
}
}
Now the problem is I know beforehand that I will be using countingwords and createCustomParagraph as private methods.
So, in that cases should I go with:
creating them as public and follow tdd cycle.
make them private.
delete the tests for them(as the methods are now private and inaccessible for tests). I think this is quite cumbersome and incorrect way to do tdd.
I am confused about this.Everyone says write code only after you write a failing test, but here if I know I am going to write a private method then how will I do this?
I request you to correct me if I am wrong somewhere. Also if possible give some real example...
Also, I fear that most of the time I will be editing tests or removing them due to access specifiers problems or refactoring ...
Note : This is not a duplicate question. I don't have good answer for realtime situations.In all examples I have seen, they show only a single class with default or public access specifiers, so they really don't show how exactly to work in realtime project.
Upvotes: 5
Views: 1285
Reputation: 3116
Very good question. I also asked it many times. And in general the answers said that you have to think about unit tests which goes before an implementation of main functionality like about frames. These frames strictly define the functionality.
So you even may don't know about private methods before you are going to implement some particular classes. But since you have a set of RED tests, the one thing you must do is to make them green. Doesn't matter how you will do it (public or private methods).
A goal number one is to write minimum lines of code, which should be covered by the unit tests. I covered TDD topic more deeply on my blog.
Upvotes: 0
Reputation: 96385
If a method is an implementation detail of the primary thing you're building which ought to remain private, that doesn't mean there's no way to write a test for it. You can make that functionality part of another class where it can be public, writing tests that exercise it directly, then call that privately from the primary thing. That way you can test the private methods, no tests get deleted, and you don't have to go through contortions testing something indirectly when the thing using it may not expose access to everything you want to test. And now instead of having private methods that are concealed bits of gnarly code, you have well-tested building blocks ready for reuse somewhere else.
Upvotes: 1
Reputation: 141
From my personal experience, you are testing the class and the interface to the class by the rest of your application. Your TDD test cases should be written against the public methods of your class. The point is to test that when stimulated, the class outputs the desired results to pass your test criteria. Internal private methods will be tested as a part of the public interface testing, but the goal is to verify that the publicly accessible interface is working. You say you know ahead of time that the private methods will be used, but if someone refactors how things are done in the class without changing the external behavior you will still be able to use your existing tests and verify that refactoring has not broken a previously working method.
Upvotes: 4