I am working OCUnit Test case
- (NSDictionary*)Event:(EventBase*)event
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
I found this method to write the test case
In my Test Case Class i pass the event value valid,invalid and nil for the above method
-(void)testEventNil{
NSDictionary *t_Dict;
EventClass *t_EventClass = [[EventClass alloc]init];
t_Dict = [t_EventClass Event:nil];
STAssertNil (t_Dict, #"Return nil");
}
-(void)testEventNil{
NSDictionary *t_Dict;
NSMutableDictionary *invalid;
[invalid setObject:#"1324" forKey #"Number"];
EventClass *t_EventClass = [[EventClass alloc]init];
t_Dict = [t_EventClass Event:];
STAssertNil (t_Dict, #"Return nil");
}
-(void)testEventvalid{
NSDictionary *t_Dict;
NSMutableDictionary *invalid;
[invalid setObject:#"WorkNameEvent" forKey #"EventNameKey"];
EventClass *t_EventClass = [[EventClass alloc]init];
t_Dict = [t_EventClass Event:];
STAssertNotNil (t_Dict, #"Return nil");
}
Its gives me error unrecognized selector sent to instance
Can any one advice me for fixing the issue
#All
Thanks in advance
Your code has multiple errors. I can't make sense of it.
You are trying to test a method that is designed to throw an error. Maybe it is intended to be overriden? The only possible test as it is now is
EventClass *event = [EventClass new];
STAssertThrows([t_EventClass Event:nil],#"Should throw an error.");
When you write: t_Dict = [t_EventClass Event:]; you are not passing any parameter to the Event: method.
This doesn't work either:
NSMutableDictionary *invalid;
[invalid setObject:#"WorkNameEvent" forKey #"EventNameKey"];
because you didn't initialize the dictionary. That is,
NSMutableDictionary *invalid = [NSMutableDictionary new];
The convention in Objective-C is to name methods and variables using camel case, in this case event: instead Event:, and dic instead t_Dic.
Related
I'm trying to test out using static libraries, and am calling this method (which is in the static library)
-(NSMutableDictionary *)parseJSONfromURL:(NSURL *)url{
__strong NSMutableDictionary *json;
[self.delegate isParsing:(url != nil)];
if (url == nil) {
[NSException raise:NSArgumentDomain format:#"The passed url argument cannot be nil"];
}
NSError *err;
json = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:url] options:NSJSONReadingMutableLeaves error:&err];
if (err) {
[json setObject:err forKey:#"error"];
}
while (json == nil) {
NSLog(#"waiting...");
}
[self.delegate isParsing:NO];
[self.delegate didFinishParsing:(json != nil)];
return json;
}
I would expect the while loop to be infinite since json is returning null, but the delegate method didFinishParsing gets sent, meaning it isn't null.
like this (ACParser is a class in the library)
ACParser *p = [[ACParser alloc] initWithDelegate:self];
dictionary = [p parseJSONfromURL:[NSURL URLWithString:#"http://www.a-cstudios.com/text.json"]];
dictionary is declared like this
__strong NSMutableDictionary *dictionary;
the JSON at that URL is very simple
{
"text" : "testing"
}
however, every time this is called, in the delegate method didFinishParsing:, logging dictionary returns (null). What am I doing wrong here? Is it because I'm calling it from a static library?
Try adding this:
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]] options:NSJSONReadingAllowFragments error:nil]);
in there and see if it prints out your expected JSON. If it doesnt, your URL is wrong. If it does, then your data isnt being retained. Try instantiating your json variable like this:
NSMutableDictionary *json = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:url] options:NSJSONReadingMutableLeaves error:&err]];
"json" within "parseJSONfromURL" is autoreleased / out of scope as soon as that method returns so it never has a chance to get assigned to your strong "dictionary" property.
That's why you are seeing NULL.
Try setting the property within your parseJSONfromURL method and see if that works, or create a non-autoreleased dictionary and return that.
I have an array which I want to validate: {"2","+","3","=","5"}
So how would I do it? I found DDMathParser and theoretically I would be able to validate my expression like so:
NSString *expression = [array componentsJoinedByString:#""];
NSError *error = nil;
DDExpression *e = [DDExpression expressionFromString:expression error:&error];
if (error == nil) {
NSLog(#"parsed: %#", e);
NSNumber * result = [e evaluateWithSubstitutions:expression error:&error];
//error: No visible #interface for 'DDExpression' declares the selector 'evaluateWithSubstitutions:error:'
}
Any thoughts why? I must mention this method is inside my singleton but when I moved it to my view controller error stayed.
Assuming you are using this project (GiHub link), I did not see a method evaluateWithSubstitutions:error:.
From the GitHub project, it looks like the full method signature is (source, line 33):
- (NSNumber *) evaluateWithSubstitutions:(NSDictionary *)substitutions evaluator:(DDMathEvaluator *)evaluator error:(NSError **)error;
is there a shorter way to do this?
iam fetching all core data objects with some predicate and then parsing them to JSON, using RestKit and defined mapping... i still want to use RestKit, but cant it be done more simple?
- (NSArray *)serializedManagedObjectClass:(Class)managedObjectClass updatedSinceRevision:(long long)revision {
NSArray * managedObjects = [managedObjectClass MR_findAllSortedBy:#"createdDate" ascending:YES withPredicate:[NSPredicate predicateWithFormat:#"revision > %lld", revision]];
NSError * error = nil;
NSMutableArray * serializedObjects = [[NSMutableArray alloc] initWithCapacity:[managedObjects count]];
for (NSManagedObject * managedObject in managedObjects) {
id object = [NSMutableDictionary new];
RKObjectMappingOperation * op = [RKObjectMappingOperation mappingOperationFromObject:managedObject toObject:object withMapping:[self.objectManager.mappingProvider serializationMappingForClass:managedObjectClass]];
BOOL success = [op performMapping:&error];
if ((success) && (error == nil) && (object)) {
[serializedObjects addObject:object];
} else {
ALog(#"Serialization problem with %#, possible error %#", managedObject, error);
}
}
return serializedObjects;
}
You don't need to map each object individually. As long as you have set the serialization mapping for that class, RestKit will handle the serialization when you try to send instances of that object. It looks like you have already created and assigned the mapping for the class.
Now, just add your array of managed objects to your dictionary of parameters that are being sent to the server. RestKit should then map each object according to the mapping provided.
why is "error:&error" used here (objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
wouldn't an object in objective-c be effectively pass-by-reference anyway?
The argument type for error: is NSError** (i.e. a pointer to a pointer to an object). This permits the moc object to allocate and initialize a new NSError object as required. It is a common pattern, especially in Cocoa.
The NSError documentation gives some indication of the motivation for this approach:
Applications may choose to create subclasses of NSError to provide better localized error strings by overriding localizedDescription.
Passing in an NSError** argument allows that method to return any subclass of NSError that makes sense. If you passed in NSError*, you would have to supply an existing NSError object, and there would be no way for the method to return a different object from the one you passed in.
To be clear, the method could look something like this:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError**)error {
...
if ((error != NULL) && (some_error_condition)) {
*error = [[[SomeNSErrorSubclass alloc] init...] autorelease];
return nil;
}
}
Note that this also allows the calling code to ignore errors by simply passing in NULL for the error: parameter, as follows:
NSArray *array = [moc executeFetchRequest:request error:NULL];
Update: (in response to questions):
There are two reasons why the argument type has to be NSError** instead of NSError*: 1. variable scoping rules, and 2. NSError instances are imutable.
Reason #1: variable scoping rules
Let's assume that the function declaration were to look like this:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error;
And we were to call the function like this:
NSError * error = nil;
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }
When you pass in a variable this way, the function body will not be able to modify the value of that variable (i.e. the function body will not be able to create a new variable to replace the existing one). For example, the following variable assignments will exist only in the local scope of the function. The calling code will still see error == nil.
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error = [[[NSError alloc] init...] autorelease]; // local only
error = [[[SomeNSErrorSubclass alloc] init...] autorelease]; // local only
}
Reason #2: instances of NSError are immutable
Let's keep the same function declaration, but call the function like this:
NSError * error = [[[NSError alloc] init...] autorelease];
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }
First of all, the variable scoping rules guarantee that error can not be nil, so the if (error != nil) { ... condition will always be true, but even if you wanted to check for specific error information inside the if block, you would be out of luck because instances of NSError are immutable. This means that once they are created, you cannot modify their properties, so the function would not be able to change the domain or userInfo of that NSError instance that you created in the calling code.
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error.domain = ... // not allowed!
error.userInfo = ... // not allowed!
}
It's effectively another return value. The error is not dominant by convention in Cocoa when there is a return value for the operation. When an error is encountered, it may be returned to you by this out parameter.
In the case of NSError, it works this way because NSError is not a mutable type - its fields are set at initialization and never mutated. Therefore, you cannot pass an NSError as usual and set the error code.
Currently, I have a class that is parsing XML and sending the dictionary that the XML is parsed to to a view controller.
Here is a snippet of the code that sends the dictionary to the other class (where "response" is the dictionary):
if ([elementName isEqualToString:#"SessionData"])
{
// We reached the end of the XML document
// dumps dictionary into log
NSLog(#"Dump:%#", [response description]);
// sends dictionary to the VC
CardSetupViewController *setup = [[CardSetupViewController alloc]init];
setup.response = self.response;
//checks
NSLog(#"%# lololololol", [setup.response description]); //THIS WORKS FINE!!
return;
}
At that point, the code works fine. That NSLog marked with //THIS WORKS FINE!! works... obviously. Here is the method in the ViewController:
- (BOOL)authorize //this
{
AddCard *addCard = [[AddCard alloc]init];
ServerConnection *connection = [[ServerConnection alloc]init];
//XMLParser *xmlParser = [[XMLParser alloc]initXMLParser];
//serverReturn posts the data and is the ACTUAL server response in NSData form
NSData *serverReturn = [connection postData:[addCard textBoxToXml:
[self nameOnCardGet]:
[self ccNumGet]:
[self expMoGet]:
[self expYrGet]:
[self cvvGet]:
[self zipGet]:
[self nickNameGet]:
[self pinGet]]];
//This takes the information from the server and parses it to "response"
//Creates and inits NSXMLParser Object
NSXMLParser *nsXmlparser = [[NSXMLParser alloc] initWithData:serverReturn];
//Create and init our delegate
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//set delegate
[nsXmlparser setDelegate:(id <NSXMLParserDelegate>) parser];
//initiates self.response THIS MAY NOT BE NEEDED
//response = [[NSMutableDictionary alloc]init];
//parsing
BOOL success = [nsXmlparser parse];
//error catch testing
if (success) {
NSLog(#"No errors");
}
else {
NSLog(#"Error parsing document!");
}
//dump
NSLog(#"ZOMG CHECK DIS OUT%#", [response description]);
return NO;
}
Basically, the NSLog that states "ZOMG CHECK DIS OUT" is returning (null) and I can't figure out why. No compilation errors, it is a property/synthesize as well. Any ideas?
Thanks in advance. Oh, and please excuse my NSLog comments. I had to differentiate from different parts of the code, and I was in a good mood.
Edit: I am using Automatic Reference Counting. Don't worry, nothing is leaking.
In your first code block, you generate a CardSetupViewController and then leak it. It is unrelated to whatever object is running the second code block. I assume that your second view controller is from your NIB?
Note that you're also leaking your NSXMLParser.
Your [response description], whatever that is, is probably an autoreleased object that gets released before ZOMG CHECK DIS OUT. Retain it and see if that works. Don't forget to release it when you're done with it.