1

I have a flow in my app that inserts Response objects into an array, This is the response object:

@interface AppResponse : NSObject

@property (nonatomic, assign) MotSDKState  state;
@property (strong, nonatomic) NSError * _Nullable error;
@property (nonatomic, assign) NSInteger errorCode;
@property (strong, nonatomic) NSDictionary * _Nullable response;

@end

I want to check at the end of the flow if the array is correct, so I create a test:

var err = AppResponse()
err.errorCode = 1000
err.state = .failed
let expectedArray = [err]
XCTAssertEqual(self.responsesArray, expectedArray)

I also tried with Nimble:

expect(self.responsesArray).to(equal(expectedArray))

And I get for both of them this unit test failed error:

error: -[****.**** *****] : failed - expected to equal <[<Appesponse: 0x600003288240>]>, got <[<Appesponse: 0x6000032948d0>]>

Any idea what is the problem? how I can compare two arrays of objects?

Clay Bridges
  • 11,602
  • 10
  • 68
  • 118
YosiFZ
  • 7,792
  • 21
  • 114
  • 221
  • https://stackoverflow.com/questions/19464261/xctassertequal-fails-to-compare-two-string-values ? You should use `XCTAssertEqualObjects`, or use XCAssertEqualTrue([self.responsoeArray isEqualTo: [AppResponose]])`, something like that. – Larme Feb 19 '23 at 14:35
  • I'm pretty sure Swift knows that `[err]` is of type `[AppResponse]`, so I think all that casting is unnecessary. Even if it were, adding a `let expectedArray = [err]` would clarify this code immensely. I edited the question to make the change. – Clay Bridges Feb 20 '23 at 21:15

1 Answers1

2

Caveat

I'm assuming we're seeing most of the AppResponse code, and that you haven't implemented an [AppResponse isEqual:] method. If you have:

  • this answer doesn't apply
  • you possibly should include it with the question

Answer

Consider this Swift code (which maybe should have been the first thing you tried):

let a = AppResponse()
let b = AppResponse()

print(a == b) // prints "false"
print(a == a) // prints "true"

Behind the scenes, these last two lines are equivalent to:

print(a.isEqual(b))
print(a.isEqual(a))

which is the Objective-C equality method, [NSObject isEqual:] (see here).

The default implementation of that method just compares the pointers to the objects, not their contents. As we showed above, it will always be false unless you compare literally the same object.

If you want these comparisons to work, you need an [AppResponse isEqual:] method comparing AppResponse objects by their properties. Because you are using these in arrays, I think that also implies needing a compliant [AppResponse hash] method. There are many guides to help you with that, e.g. this one.

Clay Bridges
  • 11,602
  • 10
  • 68
  • 118