2017-01-01 3 views
1

Я начал писать модульные тесты iOS сегодня с помощью подхода BDD. У меня есть вопрос относительно заявлений guard и получения покрытия 100% кода.Как получить тестовое покрытие для отчета об удержании Fall-through

У меня есть следующий код, который обрабатывает преобразование Data в Customer объектов.

internal final class func customer(from data: Data) -> Customer? { 
    do { 
     guard let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: []) as? Dictionary<String, Any> else { 
      return nil 
     } 
     var customerFirstName: String? = nil 
     var customerLastName: String 
     if let firstName = jsonDictionary["first_name"] as? String { 
      customerFirstName = firstName 
     } 
     guard let lastName = jsonDictionary["last_name"] as? String else { 
      return nil 
     } 
     customerLastName = lastName 
     return Customer(firstName: customerFirstName, lastName: customerLastName) 
    } catch { 
     return nil 
    } 
} 

Когда наш бэкэнд был создан, некоторым клиентам была предоставлена ​​только фамилия, в которой содержались их имена и фамилии. Вот почему имя клиента является необязательным; их полное имя может быть значением для last_name.

В моем коде имя пользователя не обязательно, пока требуется их фамилия. Если их фамилия не возвращается в полученном JSON из сетевого запроса, я не создаю клиента. Кроме того, если код Data не может быть сериализован в Dictionary, клиент не будет создан.

У меня есть два файла JSON, оба из которых содержат информацию о клиенте, которую я использую для тестирования обоих сценариев.

Один не содержит первое имя в формате JSON:

{ 
    "first_name": null, 
    "last_name": "Test Name", 
} 

Другой содержит первое имя в формате JSON:

{ 
    "first_name": "Test", 
    "last_name": "Name", 
} 

В моем тестовом модуле, используя Быстрый и ловкий, я обрабатывающий создание Customer, когда первое имя не доступно, и когда:

override func spec() { 
    super.spec() 
    let bundle = Bundle(for: type(of: self)) 
    describe("customer") { 
     context("whenAllDataAvailable") { 
      it("createsSuccessfully") { 
       let path = bundle.path(forResource: "CustomerValidFullName", ofType: "json", inDirectory: "ResponseStubs")! 
       let url = URL(fileURLWithPath: path) 
       let data = try! Data(contentsOf: url) 
       let customer = DataTransformer.customer(from: data) 
       expect(customer).toNot(beNil()) 
      } 
     } 
     context("whenMissingLastName") { 
      it("createsUnsuccessfully") { 
       let path = bundle.path(forResource: "CustomerMissingLastName", ofType: "json", inDirectory: "ResponseStubs")! 
       let url = URL(fileURLWithPath: path) 
       let data = try! Data(contentsOf: url) 
       let customer = DataTransformer.customer(from: data) 
       expect(customer).to(beNil()) 
      } 
     } 
    } 
} 

Это гарантирует, что я создаю Customer, когда первое имя отсутствует или присутствует в возвращенном JSON.

Как я могу получить 100% -ное покрытие кода этого метода, используя BDD, когда мой код не удаляет предложения else операторов guard, поскольку данные могут быть превращены в действительные объекты JSON? Должен ли я просто добавить еще один файл .json с данными, которые нельзя преобразовать в объект JSON, чтобы не создавать Customer, а также файл .json, содержащий недостающий last_name, чтобы гарантировать, что Customer не создан?

Я просто передумал концепцию покрытия 100% кода? Мне даже нужно, чтобы были проверены предложения else утвержденных заявлений guard? Есть ли у меня подходящий подход, используя метод BDD?

ответ

1

Просто напишите, какой бы JSON вы ни хотели - искажены во всех отношениях, о которых вы можете думать. Примеры:

  • Вы можете ударить по обработке исключений с помощью чего-то неправильного JSON.
  • Вы можете поразить свой первый guard чем-то, что представляет собой массив JSON, а не словарь.

Как говорится, вам нужно только покрыть код, который вы хотите быть правильным.

TDD и BDD связаны между собой.В TDD вы сначала напишите неудачный тест. Затем вы должны написать код, который проходит этот тест как можно быстрее. Наконец, вы очистите свой код, чтобы сделать его лучше. Похоже, вы добавляете тесты после факта.

Кстати, ваши тесты были бы намного яснее, если бы вы не использовали внешние файлы, но поставили JSON прямо в ваши тесты. Вот скринкаст, показывающий, как я TDD начинаю конверсию JSON. Скринкаст находится в Objective-C, но принципы те же: http://qualitycoding.org/tdd-json-parsing/

+0

@ JonRein Я ценю ваше понимание! Могу ли я спросить, как вы пришли к выводу, что я написал свои тесты после факта? Это именно то, что я сделал, но мне любопытно, почему вы пришли к такому выводу. Я определенно изучаю ваши концепции и надеюсь лучше понять. –

+0

@NickKohrn Поскольку, когда код управляется с помощью теста, вы не можете писать код, который не удовлетворяет тесту. Поэтому вы не спрашиваете: «У меня есть код, как я могу его покрыть?» –

Смежные вопросы