简体   繁体   中英

Should integration tests redo unit tests that use mocking?

While writing unit tests I will check only one class at a time. If I need to use additional classes then I will use mocking to make sure that test is independent.

Later I want to write integration tests, should I just copy/paste all unit tests that use mocking and test them after removing mock objects?

Example code:

public class Event
{
    string title;
    List<Hour> hoursList = new List<Hour>();
    public Event(string title) { this.title = title; }
    public void AddHour(Hour newHour) { hoursList.Add(newHour); }
    public int HourCount() { return hoursList.Count; }
    public int TotalDuration() {
        int total = 0;
        foreach (var hour in hoursList)
        total += hour.GetDuration();
        return total;
    }
}
public class Hour
{
    string start;
    string end;
    public Hour(string start, string end) { this.start = start; this.end = end; }
    public virtual int GetDuration() { /* algorightm calculating duration in minutes */  }
}

Example test:

int expected = 165;
Event Concert = new Event("Local band concert");
Mock<Hour> ehMock = new Mock<Hour>("07:00", "08:30");
ehMock.Setup(x => x.GetDuration()).Returns(90);
Mock<Hour> ehMock2 = new Mock<Hour>("19:15", "20:30");
ehMock2.Setup(x => x.GetDuration()).Returns(75);
Concert.AddHour(ehMock.Object);
Concert.AddHour(ehMock2.Object);
Assert.AreEqual(expected, Concert.TotalDuration());

In above unit test I'm testing TotalDurationmethod from Event class, the Hour class is mocked and I override the GetDuration() method. Now should I use the same test for integration testing, but without the Mock?

Maybe above example is too simple and integration testing isn't required. If I would have more advanced unit test then the integration test of same functionality is recommended?

A more abstract answer: those two things have completely different scope.

Unit tests exist to test all aspects of your individual units. All units, all their functionality. To be tested in isolation. In other words: you build a whole bunch of lego stones, and your unit tests tell you that all these building blocks do exactly what they are supposed to do.

On the other hand: integration tests boil down to ensure proper integration . Meaning: you think up your most important "paths", that you want to be taken, and you write integration/function tests to hammer those.

The whole point of the testing pyramid is that you keep your unit tests, so that you can write a much smaller number of integration tests. Because the unit tests run quickly, and help you to quickly identify and fix bugs. Integration tests are much more important, but also more expensive*, and you only use them for things that you can't properly unit test.

So: of course integration tests will "test" things that your unit tests verified already. But you do not want to simply turn all unit tests into integration tests.

In this exact case you gain nothing from mocking since you are not setting up anything in ehMock , so having integration test with no mocking would simply do the same. Moreover, adding parameters to the constructor like "07:00" means you are actually working against mocking as this become one exact case all the time. Tldr; I would call this example an integration test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM