0

This my code below I want to use unit testing for this file nothing else. I want to know if it is possible to unit test in XCTest to this code

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Presenter : NSObject
@property (nonatomic, retain) NSString *Name;
@property (nonatomic, retain) NSString *Topic;
@property (nonatomic, retain) NSString *Date;
@property (nonatomic, retain) NSString *Time;
@property (nonatomic, retain) NSString *Location;
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) NSMutableDictionary *rattings;
@property (nonatomic, assign) BOOL isLiked;



@end

This the M file:

#import "Presenter.h"

@implementation Presenter

- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        self.Name = [coder decodeObjectForKey:@"Name"];
        self.Topic = [coder decodeObjectForKey:@"Topic"];
        self.Date = [coder decodeObjectForKey:@"Date"];
        self.Time = [coder decodeObjectForKey:@"Time"];
        self.Location = [coder decodeObjectForKey:@"Location"];
        self.image = [coder decodeObjectForKey:@"image"];
        self.rattings = [coder decodeObjectForKey:@"rattings"];
        self.isLiked = [coder decodeBoolForKey:@"isLiked"];

    }

    return self;


}

- (void) encodeWithCoder: (NSCoder *)coder
{
    [coder encodeObject: self.Name forKey:@"Name"];
    [coder encodeObject: self.Topic forKey:@"Topic"];
    [coder encodeObject: self.Date forKey:@"Date"];
    [coder encodeObject: self.Time forKey:@"Time"];
    [coder encodeObject: self.Location forKey:@"Location"];
    [coder encodeObject: self.image forKey:@"image"];
    [coder encodeObject: self.rattings forKey:@"rattings"];
    [coder encodeBool: self.isLiked forKey:@"isLiked"];

}


@end

I found this about NScoder unit testing

How to unit test NSCoding?

and tried to apply it however my attempt at it gives out that error: caught "NSInvalidArgumentException", "-[__NSCFConstantString countByEnumeratingWithState:objects:count:]: unrecognized selector

- (void)testName {
    NSLog(@"%@ start", self.name);   // self.name is the name of the test-case method.
    NSKeyedArchiver *archive = [[NSKeyedArchiver alloc] initForWritingWithMutableData:(NSMutableData *)presenter];
    [archive encodeObject:presenter forKey:@"Name"];
    for (NSString *Name in presenter.Name) {
        [archive encodeObject:[presenter valueForKey:Name] forKey:@"Name"];
    }
    XCTAssertTrue([[presenter Name] isEqualToString:@"Name"], "Name");
    NSLog(@"%@ end", self.name);
}
Community
  • 1
  • 1
Walee
  • 1
  • 2
  • Why are you incorrectly casting `presenter` to `NSMutableData`? Why do you have a `for` loop on a single `NSString`? – rmaddy Dec 11 '15 at 01:05
  • BTW - the most useless words a programmer can use is "it doesn't work". Please clearly explain in what way the code doesn't do what you expect. Do you get compiler warnings or errors? Does the app build but crash? Does it run but do something different than expected? For any of those, provide clear, specific details about the issue. – rmaddy Dec 11 '15 at 01:15
  • Sorry but the this is what I get when I run the test case: Collection expression type 'NSString *' may not respond to 'countByEnumeratingWithState:objects:count: – Walee Dec 11 '15 at 01:32
  • Caught "NSInvalidArgumentException", "-[__NSCFConstantString countByEnumeratingWithState:objects:count:]: unrecognized selector – Walee Dec 11 '15 at 01:33
  • As I said, why are you trying to iterate over a single NSString? You can't. – rmaddy Dec 11 '15 at 01:39
  • Everything I found suggest I use that so I casted to able it work. what do you suggest me to do as far as unit testing the Name property if it exist? – Walee Dec 11 '15 at 01:44

1 Answers1

0

You should really start by reading the documentation to learn how to use NSKeyedArchiver and NSKeyedUnarchiver.

Here is how your method should look like :

- (void)testName
{
    NSLog(@"%@ start", self.name);   // self.name is the name of the test-case method.

    Presenter *presenter = [[Presenter alloc] init];
    presenter.Name = @"John";
    NSMutableData *presenterData = [NSMutableData data];

    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:presenterData];
    [archiver encodeObject:presenter forKey:@"presenter"];
    [archiver finishEncoding];

    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:presenterData];
    Presenter *decodedPresenter = [unarchiver decodeObjectForKey:@"presenter"];
    [unarchiver finishDecoding];

    XCTAssertTrue([decodedPresenter.Name isEqualToString:presenter.Name], "Name");

    NSLog(@"%@ end", self.name);
}

But you could do this in a much simpler way with factory methods :

- (void)testName
{
    NSLog(@"%@ start", self.name);   // self.name is the name of the test-case method.

    Presenter *presenter = [[Presenter alloc] init];
    presenter.Name = @"John";

    NSData *presenterData = [NSKeyedArchiver archivedDataWithRootObject:presenter];
    Presenter *decodedPresenter = [NSKeyedUnarchiver unarchiveObjectWithData:presenterData];

    XCTAssertTrue([decodedPresenter.Name isEqualToString:presenter.Name], "Name");

    NSLog(@"%@ end", self.name);
}
deadbeef
  • 5,409
  • 2
  • 17
  • 47