0

I have to write unit tests for some classes my group is developing. The classes are fairly simple, and I'm not sure how to best test them.

public class MyObjectRegistry
{
    private myDataSetMapper = new MyDataSetMapper();

    public boolean StoreObjects(list<MyObject> myObjectList)
    {
        myDataSetMapper.StoreObjects(myObjectList);
    }
}

public class  MyDataSetMapper
{
    public boolean StoreObjects(list<MyObject> myObjectList)
    {
        for(MyObject myObj: myObjectList)
        {
            boolean result = StoreObject(myObj);
        }
    }

    private boolean StoreObject(MyObject myObject)
    {
        //Store the object in a database
    }
}

So my question is how to test the MyObjectRegistry.StoreObjects and MyDataSetWrapper.StoreObjects methods since there's no real logic other than a foreach loop and calling out to another method.

I've looked around the web and found that I think I'm looking at a "facade" class/method, but I'm still unclear on what would I should test/assert in the test method.

3
  • 1
    It's unclear exactly what you're trying to do here. Why does MyObjectRegistry even exist? What happens to result? What gets returned from StoreObjects? Does StoreObject contain all the database logic, or is there another class that does that? I think if you wrote your tests first, you'd end up with an entirely different design, but too much is missing to assert that for sure.
    – pdr
    Nov 25, 2013 at 18:49
  • 1
    Pretend you can't see the source code inside of your classes and you have no idea how they work, what would you test then to make sure the class is working as intended?
    – Mike
    Nov 25, 2013 at 18:49
  • Aside, I think java method names use lower case camel casing. C# usually uses upper case.
    – jordan
    May 25, 2014 at 12:59

3 Answers 3

2

So unit tests are there to test logic, not plumbing. You don't have any logic in your (albeit small) example so it dosent need testing.

Generally speaking it should be obvious what needs testing in a method since it does one thing and its name tells you what it does. If that isnt the case you should probably look into breaking your code into smaller components.

0

The problem you are facing is the result of "bad" class design. Specifically MyObjectRegistry was not designed to facilitate unit testing. Luckily, reflection allows you to set private values of classes.

Here is what I would do in your situation:

  1. Create a mock version of MyObjectRegistry; probably using a List, a Map, or, perhaps, a Map of List ojects.
  2. At the start of your junit test (perhaps in class setup) create a MyObjectRegistry instance then set the myDataSetMapper member to the mock version of the MyDataSetMapper class.
  3. Call the storeObjects method then check to see that the values which were passed to the storeObjects method were added to the mocked MyObjectRegistry object.

Assuming that the database access code in not inside the MyDataSetMapper.storeObject() method, do the same thing for MyDataSetMapper with a mocked data access object.

0

The problem is that MyObjectRegistry creates a new MyDataSetMapper, instead of having that dependency injected. The appearence of "new" creates a hard, compile-time dependency on MyDataSetMapper. There are two ways to go:

  • Use a reflection utility (Like ReflectionTestUtils) to forcibly set that variable to a mock instance of MyDataSetMapper. Yuck!

  • Change the class so that instead of instantiating MyDataSetMapper, it gets injected as a dependency instead:

    public MyObjectRegistry(MyDataSetMapper mapper) { this.myDataSetMapper = mapper; }

Now you can instantiate the registry with an injected mock instance, and you're testing the unit under test (the registry object) and not the MyDataSetMapper.

  • If MyDataSetMapper talks directly to the database, then there's no point in testing it in isolation, since it's by nature an integration object. You can test that out in integration tests, or just by running and exercising the application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.