Тестирование: проверка ввода параметров - PullRequest
2 голосов
/ 05 марта 2011

В следующем коде мне было интересно, можно ли корректировать тесты, выполняющие проверку имени.Потому что, как только я добавляю код, который проверяет, что идентификатор не может быть нулевым, мои первые 3 теста не пройдены.

То же самое относится и к последним 3 тестам, которые проводят тестирование id.Я должен использовать 'foo' в качестве имени, иначе эти тесты тоже не пройдут.Не уверен, что это нормально?

Код для тестирования:

class Error

class Node
    constructor: (name, id) ->
        if not name?
            throw new Error('Name cannot be null')

        @name = name

        if not id?
            throw new Error('Id cannot be null')

        @id = id

window.Node = Node

Спецификация:

node_spec = describe 'Node', () ->

    it 'should have the name foo', () ->
        expect( new Node('foo').name ).toEqual('foo')

    it 'should have the name bar', () ->
        expect( new Node('bar').name ).toEqual('bar')

    it 'should throw an error if the name is null', () ->
        expect( () -> new Node() ).toThrow()

    it 'should have an id of 0', () ->
        expect( new Node('foo', 0).id ).toEqual(0)

    it 'should have an of 1', () ->
        expect( new Node('foo', 1).id ).toEqual(1)

    it 'should throw an error if id is null', () ->
        expect( new Node('foo') ).toThrow()

window.node_spec = node_spec

Обновление: Я думаю, одинРешение состоит в том, чтобы иметь методы getter и setter для идентификатора и имени и протестировать их.

Ответы [ 2 ]

3 голосов
/ 05 марта 2011

Отредактировано после комментария Матыра ниже: Сначала я полагал, что это связано с причудой оператора new, поскольку в некоторых тестах используется синтаксис new Foo().bar. Однако new ведет себя так, как ожидал Пикелс в этих обстоятельствах. Таким образом, хотя этот ответ не является решением указанной проблемы, вот обзор для потомков:

Когда вы пишете

new A().B

вы ссылаетесь на свойство B нового экземпляра A.

Но если вы напишите

new A.B()

(или просто new A.B - CoffeeScript неявно добавляет скобки в конец цели new, если они отсутствуют), тогда вы создаете новый экземпляр A.B. Это довольно запутанно - что такое new A().B()? - потому что у оператора new есть свои особые правила приоритета. Поэтому я рекомендую использовать скобки для пояснения такого кода, например,

(new A).B
new (A.B)

Здесь было обсуждение о попытке сделать это поведение более интуитивным в CoffeeScript, но после энергичных усилий было установлено, что "лекарство было хуже, чем болезнь".

1 голос
/ 06 марта 2011

Позвольте мне попробовать это снова: сейчас у вас есть три теста, которые не пройдены.Давайте разберемся, как устранить каждую ошибку.

Тест # 1

expect( new Node('foo').name ).toEqual('foo')

Получается ошибка, поскольку отсутствует id.Я бы сохранил тест для этой ошибки,

expect( new Node('foo') ).toThrow()

и переписал бы тест # 1, чтобы объявить действительный, безошибочный экземпляр Node, так же как вы делаете с тестовыми строками id:

expect( new Node('foo', 1).name ).toEqual('foo')

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

Test # 2

expect( new Node('bar').name ).toEqual('bar')

Это в основном то же самое, что test # 1.На самом деле, я бы сказал, что вы на самом деле слишком тщательно тестируете здесь.Вопрос, который вы должны задать: есть ли у меня основания полагать, что передача 'bar' в качестве имени вместо 'foo' приведет к другому поведению?Я бы сказал «нет»

Так что я бы либо сразу удалил тест 'bar', либо заменил 'bar' на '' (при условии, что вы хотите разрешить пустые строки в качестве имен), так какнеуместное значение or вместо ? или if name вместо if name? может привести к тому, что '' будет вести себя иначе, чем строка длиной> 0.

Test # 3

expect( () -> new Node() ).toThrow()

Этот тест не пройден, потому что () -> new Node() определяет функцию - функцию, которая никогда не запускается.Я думаю, что вы хотите написать просто new Node().

Другие мысли

Глядя на документы Speks , звучит так, как будто предпочтительный стиль сокращается при повторном экземплярекод объявления с использованием beforeEach.Конечно, это не сработает, когда вы тестируете сам конструктор, но вы можете использовать его для большей части ваших тестов в будущем.

Вот переписанная версия вашего набора тестов, включающая всеиз этих предложений и деления тестов на три типа: те, где создается исключение, те, где ожидается нормальное поведение, и те, где объект должен вести себя правильно, но это крайний случай:

node_spec = describe 'Node', () ->

  # exception tests
  it 'should throw an error if there are no arguments', () ->
      expect( new Node() ).toThrow()

  it 'should throw an error if there is only one argument', () ->
      expect( new Node('foo') ).toThrow()

  # normal tests
  node = new Node('foo', 1)

  it 'should have an id of 1', () ->
      expect( node.id ).toEqual(1)

  it 'should have the name foo', () ->
      expect( node.name ).toEqual('foo')

  # slightly unusual case of id = 0, name = '' (convertible to false)
  node = new Node('', 0)

  it 'should have an id of 0', () ->
      expect( node.id ).toEqual(0)

  it 'should have an empty string as its name', () ->
      expect( node.name ).toEqual('')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...