Monday, May 16, 2011

Convert the best of the rest

Now that we have our database in SQL, it's time to refactor the rest of the code out the XML and into the relational database. This will give us a chance to extend test coverage into those aspects of the program.

Let's continue in the vein of the Question display. It also shows a set of answers, and these need to all be selected from the database instead of the XML table. Again, the randomization question raises it's ugly head. How can the test be shown to have selected its answers from the database?

Finding the answers goes back to the initialization of the XML questions routine, which also create word groupings. This is the method:

public static void initializeQuestions(Activity activity, AppState appState) {

Depending on the word, e.g. ends in "る", etc., possible answers will be selected from a particular grouping. Since this is where the words are loaded, this is going to be where we pull in the answers from the database as well. In fact, we just might as well go straight to the point where it's gathering the questions. This means the word group logic won't have to be replaced, because it's just loading to a hash table using the word that's been found.

The problem is that, aside from not being able to test the difference from where the answers come, I'm going to have to replace the whole thing, pretty much. I'd rather build up the module, unit testing one bit at a time. Then, when I know it's working, just substitute it in. This sounds *much* better than coding the whole thing for an hour or two and then debugging it.

Let's create a method called:

public static void initializeQuestionsSQL(Activity activity, AppState appState)

What is a way I can get this moving really easily? I'd like to create a pojo object outside that I use for all the logic except accessing the DB. Maybe I can even mock the db access.

The interesting thing about this class is it's an activity, although all the methods are static. There might be a reason for this - but I can't see it. What if we remove the extends activity?

Seem to run ok. The test cases pass, anyway. Let's leave that as a non-activity for now. So, for this one, we may be able to either extend android test case or even test case. But, we might need something from activity. It's confusing. Let's look at the "HelloAndroidTest" test from google. No, not yet. That extends IntrumentationTestCase2.

Ok, well, let's just extend TestCase and see what happens.

public void testsContructed() {
Assert.assertEquals(true, true);
}


Ok. Next, let's call a simple static method that we can build on.

Well, I'm going to go back to ActivityUnitTestCase, because the all the methods take an activity and an app state object.

We'll use the start activity since, it's the simplest:

public void testConstruct() {

AppState appState = new AppState();
appState.jlptLevel = 5;
appState.currentQuestion = 3;
setApplication(appState);

Intent intent = new Intent(getInstrumentation().getTargetContext(),
JlptQuizStartActivity.class);


JlptQuizStartActivity a = startActivity(intent, null, null);
InitUtils.initializeQuestionsSQL(a, appState);
Assert.assertEquals(true, true);
}


Ok, that works Just the way I like it - no compile, so I can use Eclipse to create the method. First unit test passed.

Let's see if we can bring the database into the picture. Let's pass it the same app state as before, which caused the word "青い" to be looked up. Since it's not displayed anywhere, I'll set up a member on the application to it, get it and check it for equality. That's probably not politically correct, since I'm changing the app to accommodate testing, but it's easy and gets me moving.


Here's the test method:

public static void initializeQuestionsSQL(JlptQuizStartActivity a,
AppState appState) {
a.testAnswer = "青い";

}

And - it works. We're off to a nice start.

No comments:

Post a Comment