Как TDD UIGestureRecognizers? - PullRequest
       4

Как TDD UIGestureRecognizers?

6 голосов
/ 04 января 2012

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

Если распознаватель жестов настроен в IB (с поддержкой iOS 5+), целевое действие настраивается при загрузке NIB / раскадровки; если сделано в коде, оно использует initWithTarget: action:, оба из которых означают, что никакое количество насмешек не сможет обнаружить цель-действие.

У меня нет идей. Если кто-нибудь успешно протестировал UIGestureRecognizer, я мог бы воспользоваться этим советом.

Ответы [ 4 ]

4 голосов
/ 04 января 2012

К сожалению, вы пытаетесь проверить класс фреймворка, который не был написан с целью тестирования и поэтому не раскрывает состояние, которое вы хотите проверить.Это затруднит утверждение о существовании пар «цель-действие», которые вы хотите проверить.В таком случае у меня есть три варианта, которые вы можете использовать, ни один из которых не является отличным решением:

Возможно, вы сможете создать подкласс UIGestureRecognizer, переопределить методы target-action, чтобы сохранить зарегистрированные пары в коллекции, которую затем сможетевыставить пользователям класса, а затем вызвать реализации этих методов суперкласса.К сожалению, тогда вы вводите новые классы просто для того, чтобы упростить тестирование, должны помнить об их использовании и, возможно, придется приводить из UIGestureRecognizer к вашему пользовательскому подклассу в зависимости от того, откуда вы получаете ссылку на распознаватель жестов.ваш тест может перебросить новые версии методов целевого действия в UIGestureRecognizer, что даст вам возможность отслеживать добавленные цели.Просто позаботьтесь о том, чтобы поменять исходные реализации методов на место, когда вы закончите, или будущие тесты будут иметь неожиданное поведение.

Наконец, вы сможете найти частный вызов API, который даст вам возможность проверитьзарегистрированные целевые действия на распознавателе жестов.Просто убедитесь, что частный вызов API остается только в вашем тестовом коде.

2 голосов
/ 04 июня 2015

Вот как я тестирую модуль распознавания жестов в Swift.Тест проверяет выполнение кода, отвечающего на жест касания.

Сначала я создаю класс помощника OnTap

class OnTap: NSObject {
  var closure: ()->()

  init(view: UIView, gesture: UIGestureRecognizer, closure:() -> ()) {
    self.closure = closure
    super.init()
    view.userInteractionEnabled = true
    view.addGestureRecognizer(gesture)
    gesture.addTarget(self, action: "didTap:")
  }

  func didTap(gesture: UIGestureRecognizer) {
    closure()
  }
}

Затем я регистрирую жест касания с помощью вида иЗакрытие обратного вызова

class MyClass {
  var onTap: OnTap?
  var didTap = false

  func setupTap() {
    let myView = UIView()
    onTap = OnTap(view: myView, gesture: UITapGestureRecognizer()) { [weak self] in
      self?.didTap = true
    }
  }
}

Наконец, я моделирую отвод в моем модульном тесте и проверяю, что закрытие было названо

class MyGestureTests: XCTestCase {
  func testRepondToGesture() {
    let obj = MyClass()
    obj.setupTap()

    obj.onTap?.didTap(UITapGestureRecognizer())

    XCTAssert(obj.didTap)
  }
}

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

1 голос
/ 22 мая 2014

Я бы предложил подкласс распознавателя жестов следующим образом:

class PanGestureRecognizer: UIPanGestureRecognizer {

    let initialTarget: Any?
    let initialAction: Selector?

    public override init(target: Any?, action: Selector?) {
        initialTarget = target
        initialAction = action
        super.init(target: target, action: action)
    }

}
0 голосов
/ 26 июня 2013

Если кто-то заинтересован в решении, использующем частный API, следующую категорию UIGestureRecognizer можно использовать для отправки действий по распознаванию жестов. Как указывает Иона, не используйте его в рабочем коде.

@interface GGGestureRecognizerTarget : NSObject{
@public
  id _target;
  SEL _action;
}    
@end

@implementation GGGestureRecognizerTarget
@end

@interface UIGestureRecognizer (GGTest)     
- (void)sendActions;   
@end    

@implementation UIGestureRecognizer (GGTest)    
- (void)sendActions{
  id targets = [self valueForKey:@"_targets"];
  for (GGGestureRecognizerTarget* target in targets) {
    [self sendActionToTarget:target];
  }
}    
- (void)sendActionToTarget:(GGGestureRecognizerTarget*)recognizerTarget{
  id target = recognizerTarget->_target;
  SEL action = recognizerTarget->_action;
  [target performSelector:action withObject:self];
}    
@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...