2013-11-27 14 views
1

NSDateFormatter 메서드를 테스트하는 가장 좋은 방법은 무엇입니까?NSDateFormatter로 취약한 단위 테스트 방지

1) 단위 테스트에서 같은 포맷 만들기 :

it(@"should format a date", ^{ 
    NSDate *date = [NSDate date]; 
    NSDateFormatter *f = [[NSDateFormatter alloc] init]; 
    [f setTimeStyle:NSDateFormatterShortStyle]; 
    [f setDateStyle:NSDateFormatterNoStyle]; 

    [[[testObject formatStringFromDate:date] should] equal:[f stringFromDate:date]]; 
}); 

- (NSString *)formatStringFromDate:(NSDate *)date { 
    NSDateFormatter *f = [[NSDateFormatter alloc] init]; 
    [f setTimeStyle:NSDateFormatterShortStyle]; 
    [f setDateStyle:NSDateFormatterNoStyle]; 

    return [f stringFromDate:date]; 
} 

내가 키위를 사용하여이 방법을 테스트 생각할 수있는 두 가지 방법이 있습니다 : 예를 들어, 내가하는 방법이 있다고 할 수 있습니다

2) 명시 적으로 의도 된 출력을 쓰기 :

it(@"should format a date", ^{ 
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:1385546122]; 
    NSDateFormatter *f = [[NSDateFormatter alloc] init]; 
    [f setTimeStyle:NSDateFormatterShortStyle]; 
    [f setDateStyle:NSDateFormatterNoStyle]; 

    [[[testObject formatStringFromDate:date] should] equal:@"9:55 am"]; 
}); 

이제 나에게, # 1은 약간 중복 보인다. 나는 본질적으로 내 단위 테스트에서이 방법을 복제하고 있기 때문에 테스트가 통과한다는 것을 알고 있습니다.

방법 # 2는 매우 불안정하기 때문에 시동기가 아닙니다. 그것은 테스트 장비의 현재 로케일이 기대하는 바를 완전히 사용합니다.

내 질문은 :이 방법을 테스트하는 데 더 적합한 방법이 있습니까, 아니면 그냥 테스트 방법 # 1로 진행해야합니까?

+1

테스트의 목적은 무엇입니까? NSDateFormatter가 작동하는지 확인하려면? –

+0

실제로'UITableViewCell'에 날짜 속성이있을 때'detailTextLabel.text'가 설정되어 있는지 테스트하고 있습니다. 나는 나의 질문을 위해 시험과 방법을 단순화했다. – squarefrog

+0

테스트 할 코드는 어디에 있습니까? 보기 컨트롤러 또는 테이블보기 셀 하위 클래스에서? – e1985

답변

1

당신이 말하고자하는 것처럼, 테스트하려는 것은 셀의 detailTextLabel의 텍스트가 날짜가있을 때 예상되는 형식으로 날짜로 설정된다는 것입니다.

이것은 여러 가지 방법으로 테스트 할 수 있습니다.

우선 날짜를 형식화 할 때마다 날짜 포맷터를 만드는 것이 효율적이지 않으며 테스트하기가 더 어렵습니다.

그래서 내가 제안하는 것은 테이블 뷰 컨트롤러의 날짜 포맷터 속성을 만드는 것입니다 : 나는 timeStyle 및 DateStyle의를 확인하는 간단한 테스트를 만들 것입니다 날짜 포맷에 대한

// .h 
@property (strong, nonatomic) NSDateFormatter *dateFormatter; 

// .m 
- (NSDateFormatter *) dateFormatter 
{ 
    if (_dateFormatter == nil) 
    { 
     _dateFormatter = [[NSDateFormatter alloc] init]; 
     [_dateFormatter setTimeStyle:NSDateFormatterShortStyle]; 
     [_dateFormatter setDateStyle:NSDateFormatterNoStyle]; 

    } 
    return _dateFormatter; 
} 

. 나는 내가 OCUnit의 주장 사용 키위에 익숙하지 않은 나는이를 가진 후

TableViewController *sut;// Instantiate the table view controller 
STAssertTrue(sut.dateFormatter.timeStyle == NSDateFormatterShortStyle, nil); 
STAssertTrue(sut.dateFormatter.dateStyle == setDateStyle:NSDateFormatterNoStyle, nil); 

을, 아이디어는 tableView:cellForRowAtIndexPath:에 의해 반환 된 셀이 포맷터에 의해 반환 된 문자열로 설정된 detailTextLabel의 텍스트가 있음을 확인하는 테스트를 만드는 것입니다 . 우리가 조롱 할 수 있도록 날짜 포맷터에서 반환 된 문자열을 테스트하는 것이 깨지기 쉽기 때문에 stringFromDate:을 붙이면 상수가 반환되고 detailTextLabel의 텍스트가 해당 상수로 설정되어 있는지 확인하십시오.

그래서 우리는 테스트를 작성합니다.

TableViewController *sut;// Instantiate the table view controller 

id mockDateFormatter = [NSDateFormatter mock]; 

NSString * const kFormattedDate = @"formattedDate"; 
NSDate * const date = [NSDate date]; 

[mockDateFormatter stub:@selector(stringFromDate:) andReturn:kFormattedDate withArguments:date,nil]; 

sut.dateFormatter = mockDateFormatter; 
sut.dates = @[date];// As an example we have an array of dates to show. In the real case we would have an array of the objects you want to show in the table view. 

[sut view];// In case we have the registered cells... 
UITableViewCell *cell = [sut tableView:sut.tableView 
       cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 

STAssertEqualObjects(cell.detailTextLabel.text, kFormattedDate, nil); 

그리고이 같은 것이 그 테스트를 만족시키는 방법 :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // I assume you have a standard cell registered in your table view 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; 

    NSDate *date = [self.dates objectAtIndex:indexPath.row]; 
    cell.detailTextLabel.text = [self.dateFormatter stringFromDate:date]; 

    return cell; 
} 
아이디어가 중요한 것은 - 내가 뭔가 잘못 할 경우 미안, 뉴질랜드 모의 객체로를 작성하려고 것

희망이 있습니다.

+0

우수한 답변, 정확히 내가 무엇을 찾고 있었습니까. 고맙습니다. – squarefrog

+1

작은 힌트 :'STAssertEquals (sut.dateFormatter.timeStyle, NSDateFormatterShortStyle, nil)'을 사용합니다. 실패 할 경우, 오류 메시지는 현재'dateStyle'이 현재 날짜 포맷터에 할당 된 것을 보여주기 때문에 약간 더 유익합니다. –