2016-04-22 4 views
0

Рассмотрим следующий класс с именем SomeClass написанный в Swift:Дразнящий с Swift

@objc class SomeClass: NSObject 
{ 
    var shouldCallBar = false 

    func foo() 
    { 
     if (shouldCallBar == true) 
     { 
      bar() 
     } 
    } 

    func bar() 
    { 
    } 
} 

Для тестирования выше класса Foo() метод (и подобные сценарии в основном написанные на Objective-C) I использовал OCMock как:

- (void) testFooBarShouldBeCalledWhenShouldCallBarIsTrue 
{ 
    SomeClass * someClass = [SomeClass new]; 

    // Create mocks. 
    id mockSomeClass = OCMPartialMock(someClass); 

    // Expect. 
    [[mockSomeClass expect] bar]; 

    // Stub. 
    someClass.shouldCallBar = YES; 

    // Run code under test. 
    [someClass foo]; 

    // Verify. 
    [mockSomeClass verify]; 

    // Stop mocking. 
    [mockSomeClass stopMocking]; 
} 

Но выше тест завершается с кодом Swift как OCMock won't works well with Swift.

Так я рассматриваю что-то вроде полностью в Swift:

class SomeClassTests: XCTestCase 
{ 
    class MockSomeClass: SomeClass 
    { 
     var isBarCalled = false 

     override func bar() 
     { 
      isBarCalled = true 
     } 
    } 

    func testBarShouldBeCalledWhenTrue() 
    { 
     let someClass = MockSomeClass() 
     someClass.shouldCallBar = true 

     someClass.foo() 

     XCTAssertTrue(someClass.isBarCalled == true) 
    } 
} 

Примечания здесь я подклассы исходного класса по испытанию и перекрывая бар(). Я вовсе не касаюсь реализации foo().

Но недостатком является то я использую MockSomeClass экземпляр для проверки Foo() из SomeClass. Это то, что мне не нравится, и not recommended.

Есть ли лучшее решение проблемы выше?

Примечания:

  • Я не говорю о Dependency Injection здесь. Инъекция зависимостей - совершенно другой подход.
  • Я сталкиваюсь с такими проблемами при тестировании кода пользовательского интерфейса в UIViewController.
  • Я думал о программировании на основе протокола, но не смог найти решение проблемы выше.
+0

Я голосовал, чтобы закрыть этот вопрос, в первую очередь, исходя из мнения. Вы представили нам рабочее решение. Вы недостаточно объяснили, почему это недостаточно для ваших нужд. Вы ищете общий «лучший» и на самом деле не обозначили * любые * критерии, которые считаются лучшими. Вот несколько [рекомендуемых чтений] (http://importblogkit.com/2016/03/how-to-ask-a-good-stack-overflow-question/) ... – nhgrif

+0

... и кстати ... существует несколько проблем с тем, как вы реализовали, но эта общая модель является правильным способом, насколько мне известно. – nhgrif

ответ

1

Итак, вы хотите, чтобы проверить, что один метод (foo) делает или не вызвать другой метод (bar). Метод foo является тестируемым, а метод bar в более широком смысле является зависимым компонентом.

Если вызов bar имеет длительные побочные эффекты, вы можете уйти с тестированием того, что побочный эффект отсутствует/нет, возможно, запросив свойство или подобное. В этом случае вам не нужны макеты или подобные.

Если побочных эффектов нет, тогда вы должны подменить зависимость. Для этого вам нужен шов , на котором вы размещаете код, который может проверить, был ли метод вызван или нет. Для этого я могу видеть только два варианта, которые Джон уже обсуждал в question you refer to.

Вы либо помещаете два метода в отдельные классы, и в этом случае граница класса является швом. Используя протокол или просто неформальное соглашение, вы можете полностью заменить класс, который реализует bar. Здесь удобна инъекция зависимостей.

Если оба метода должны оставаться в одном классе, тогда вы должны использовать границу подкласса в качестве шва, т.е.вы используете тот факт, что вы можете переопределить методы и реализовать test-specific sublass. Это проще всего, когда вы можете использовать фреймворк. Если это не вариант, вам нужно написать код самостоятельно, как и то, что вы описываете в своем вопросе.

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