Как мне выполнить юнит-тестирование класса, который зависит от другого класса, чтобы изменить состояние чего-либо? - PullRequest
1 голос
/ 29 июня 2010

У меня есть класс A, который содержит экземпляр класса B, и функция foo из A вызывает функцию set из B, которая обновляет состояние B. Вот пример кода (в Javascript):

A = function () {
    this.init = function (b) {
        this.b = b
    }

    this.foo = function (val) {
        this.b.set(val)
    }

    this.bar = function () {
        return this.b.get()
    }

}

B = function () {
    this.set = function (val) {
        this.v = val
    }

    this.get = function () {
        return this.v
    }
}

Как выполнить модульное тестирование функции foo, оставляя тест для A не зависящим от реализации B (с использованием насмешек и заглушек, а что нет)?

Ответы [ 2 ]

3 голосов
/ 29 июня 2010

Используя mocks, вы можете просто передать A mock из B, который проверит, что set был вызван с соответствующим значением.Если у вас нет фиктивной инфраструктуры, в JavaScript вы можете просто создать объект:

b = {  
       setCalled: false,
       expectedValue: <expected>
       set: function(val) {
         <check that val == this.expectedValue>
          this.setCalled = true;
       }
     }

в тесте, который вы настроили b, создайте A с указанным b, затем вызовитеA.foo и убедитесь, что b.setCalled изменено на true.Вы также можете добавить метод get к b, чтобы проверить A.bar.

. В этом случае вам также следует проверить запах Feature Envy - когда два класса тесно связаны между собойследует убедиться, что вы не используете что-то неправильно.Это может быть хорошо в вашем реальном примере, но это стоит проверить.

0 голосов
/ 12 июля 2010

Я выяснил, что лучший способ сделать это, при этом удостоверившись, что тест А не зависит от его реализации, состоит в том, чтобы создать макет Б, который имеет рабочие get и set, но записывает в временная переменная.

Пример кода для проверки A:

// Mock B
b = new function () {
    this.set = function (val) {
        this.v = val
    }

    this.get = function () {
        return this.v
    }
}

// Create an instance of A with Mock B
a = new A().init(b)

// Test A

// ...
...