How to unit test class with no logic?

2020-03-05 02:54发布

I find it easy to write unit tests for algorithms. For example, sort(List), it is easy to write tests like:

list = [2, 1, 4];
assert(sort(list) == [1, 2, 4]);

But I find it really hard to test methods that have no logic, no if statements, just a set of calls.

There are mainly 2 examples that I'd like an answer for how to unit test them:

Example 1:

Let's say I have a class that is responsible for writing some data to a file, but that data is written in a specific way by external functions (writeHeaderToFile, writeSerializedData and writeEndOfFile).

The data is not written straight as it is to the file, so if data is something like:

{
    list: [
        "item 1",
        "item 2"
    ],
    name: "aaa"
}

That doesn't mean that the file will be neither the plain version of that data (without white spaces) nor it will be a simple serialized version or encrypted version into file. The actual file binary will be something unknown to me. All I know is that I can use those 3 methods to write in the right way.

This file also contains some other information that doesn't come directly from those 3 methods, like a specific type of header (that again, I have no idea how it will be represented in the file binary).

That is the class:

class FileCreator {
    populateFileWithData(File file, Data data) {
        doBlockWithLock(file, {
            Header header;
            header.format = SomeFormat;
            header.version = SomeVersion;
            writeHeaderToFile(file, header);

            writeSerializedData(file, data);

            writeEndOfFile(file);
        });
    }

    // Private
    void doBlockWithLock(File file, Lambda block) {
        file.holdWritingLock();
        block();
        file.releaseWritingLock();
    }
}

Example 2:

class Controller {

    var screenOne = new ScreenOne();
    var screenTwo = new ScreenTwo();
    var screenThree = new ScreenThree();

    void reloadButtonWasClicked() {
        screenOne.reload();
        screenTwo.reload();
        screenThree.reload();
    }
}

For this one I could do something like this:

var mockScreenOne = Mock<ScreenOne>().reload.expectOneCall();
var mockScreenTwo = Mock<ScreenTwo>().reload.expectOneCall();
var mockScreenThree = Mock<ScreenThree>().reload.expectOneCall();

Controller controller = new Controller();
controller.screenOne = mockScreenOne;
controller.screenTwo = mockScreenTwo;
controller.screenThree = mockScreenThree;

controller.reloadButtonWasClicked();

mockScreenOne.verify();
mockScreenTwo.verify();
mockScreenThree.verify();

But I don't find much value in it since I'm just asserting that I'm doing the same thing I'm doing in the implementation. Seems like code repetition to me.


What would be the proper way of testing my 2 examples?

1条回答
▲ chillily
2楼-- · 2020-03-05 03:30

In the first example, if you wrote the messages in question and satisfied with your test coverage, there's no reason to reproduce that testing logic on FileCreator. You just need to test the FileCreator populateFileWithData method to make sure the file is written and maybe that the locking mechanism works.

You are right, your last test is rather trivial. I'd be tempted to omit writing it. But it depends. Is it likely that someone might come along and comment out one of those panel constructors? Do you have other tests that would identify such a problem?

查看更多
登录 后发表回答