使用 RSpec 进行 iPhone 控制器测试

3
我在周末花了几个小时,终于开始掌握RSpec的使用方法。现在我卡在了如何断言参数确实传递到控制器上。我正在按照Bowled over by Ruby/Cocoa example的示例,并将其适配为iPhone SDK。我在我的博客详细记录了我的进展情况,所以我会在那里提供完整的故事。简而言之,我一直按照教程操作,直到需要从文本字段中传递pin值到Bowling对象为止。RSpec一直抱怨说:"Spec::Mocks::MockExpectationError in ‘OSX::BowlingController should send the pin value to the bowling object’ Mock ‘Bowling’ expected :roll with (10) but received it with (no args) ./test/bowling_controller_spec.rb:38:”即使我确定我已经传递了一个值。这是我的代码。有人能告诉我错在哪里吗?

bowling_controller_spec.rb

require File.dirname(__FILE__) + '/test_helper'

require "BowlingController.bundle"
OSX::ns_import :BowlingController

include OSX

describe BowlingController do
  before(:each) do
    @controller = BowlingController.new  
    @bowling = mock('Bowling')
    @text_field = mock('Pins')
    @text_field.stub!(:intValue).and_return(10)
    @controller.pins = @text_field
  end

  it "should roll a ball" do
    @controller.roll
  end

  it "should roll a ball and get the value from the pins outlet" do
    @text_field.should_receive(:intValue).and_return(0)
    @controller.roll
  end

  it "should be an OSX::NSObject" do
    @controller.is_a?(OSX::NSObject).should == true
  end

  it "should have an outlet to a bowling object" do
    @controller.bowling = @bowling
  end

  it "should send the pin value to the bowling object" do
    @controller.bowling = @bowling
    @bowling.should_receive(:roll).with(10)

    @controller.roll
  end
end

BowlingController.h

#import <Foundation/Foundation.h>

@class UITextField;
@class Bowling;

@interface BowlingController : NSObject {
    UITextField* pins;
    Bowling* bowling;
}
@property (nonatomic, retain) UITextField* pins;
@property (nonatomic, retain) Bowling* bowling;

-(void) roll;
@end

BowlingController.m

#import "BowlingController.h"
#import "Bowling.h"


@implementation BowlingController
@synthesize pins;
@synthesize bowling;

-(void) roll{
    [self.bowling roll:[self.pins intValue]];
}

@end

// This initialization function gets called when we import the Ruby module.
// It doesn't need to do anything because the RubyCocoa bridge will do
// all the initialization work.
// The rbiphonetest test framework automatically generates bundles for 
// each objective-c class containing the following line. These
// can be used by your tests.
void Init_BowlingController() { }

Bowling.h

#import <Foundation/Foundation.h>

@interface Bowling : NSObject {

}
- (void) roll:(int) pins;
@end

Bowling.m

#import "Bowling.h"


@implementation Bowling
- (void) roll:(int) pins{
}

@end

// This initialization function gets called when we import the Ruby module.
// It doesn't need to do anything because the RubyCocoa bridge will do
// all the initialization work.
// The rbiphonetest test framework automatically generates bundles for 
// each objective-c class containing the following line. These
// can be used by your tests.
void Init_Bowling() { }
2个回答

3
RubyCocoa在iPhone上完全不受支持。没有桥接支持库,我认为手机上也没有任何Ruby解释器。您可能能够在模拟器中使其工作,但如果您真的尝试使用仅限于OS X的库,则无法使其在iPhone上运行。如果您真的想在iPhone上使用RubyCocoa,则需要将Ruby构建为静态库并将桥接移植到手机上,这是可行的,但可能非常困难。

0

你好!虽然我不熟悉Ruby/Cocoa如何包装外部方法调用,或者说我对Objective C也不熟悉,但是在测试中最有可能出现问题的地方似乎是将Ruby模拟对象传递给本地实现的控制器。在保龄球教程中,Ruby控制器代理将其接口公开给Cocoa桥接器,而在这个实现中,代理包装了一个公开的Cocoa接口。因此,在替换本地字段的Ruby模拟对象和替换Ruby字段的Ruby模拟对象时可能会出现问题。

然而,针对销倒测试的roll()函数成功了,所以消息传递可能是正确的,但是参数可能被篡改或丢失了。

这可能并没有太大帮助,但这是一个有趣的问题。祝你在项目中好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接