specta / expecta

A Matcher Framework for Objective-C/Cocoa
MIT License
1.59k stars 158 forks source link

beInstanceOf causes failing test when it should pass #155

Open markeissler opened 9 years ago

markeissler commented 9 years ago

I'm reopening this issue, originally reported as #123. This matcher is broken, or at least the description of its use is incorrect:

expect(x).to.beInstanceOf([Foo class]); passes if x is an instance of a class Foo

According to that description, as long as the comparison object on the left is exactly of type [Foo class] then the test should pass. In comparison, the companion matcher:

expect(x).to.beKindOf([Foo class]); passes if x is an instance of a class Foo or if x is an
instance of any class that inherits from the class Foo.

Implies that the comparison object on the left could be either of type [Foo class] or a subclass.

I'm getting the exact result as the original reporter:

expected: an instance of Foo, got an instance of Foo

What I'm expecting, is to get the same result as returned by:

expect([object class]).to.equal([Foo class]);

Either the implementation is incorrect, the documentation is incorrect, or the error is incorrect.

robb commented 9 years ago

Could it be that you have the framework containing Foo linked twice, therefore having two Foo classes around in the runtime?

We've seen this multiple times in Mantle.

markeissler commented 9 years ago

Well my Podfile has this already...

target :WonderAppTests, :exclusive => true do
  pod 'Specta', '~> 0.5'
  pod 'Expecta', '~> 0.3'
  pod 'OCMock', '~> 3.0'
end
asalom commented 9 years ago

I have the same problem with a subclass of UIView.

In the case of beKindOf:

expect(_viewController.introView).to.beKindOf([EAIntroView class]); // this fails
expect(_viewController.introView).to.beKindOf([UIView class]); // this passes

In the case of beInstanceOf both of the expectations fail

expect(_viewController.introView).to.beInstanceOf([EAIntroView class]); // this fails
expect(_viewController.introView).to.beInstanceOf([UIView class]); // this fails

PS. I have a test ensuring that the instance is not nil which passes

robb commented 9 years ago

It's not really possible to debug this without knowing what's going on in _viewController and what your setup looks like.

Does

NSAssert([_viewController.introView isKindOfClass: EAIntroView.class], @"Expected %@ to an instance of EAIntroView", _viewController.introView)

throw an assertion for you? If so, it seems like EAIntroView is linked twice.

asalom commented 9 years ago

You were right, using CocoaPods to manage my dependencies I was adding to the test target all dependencies from the main target, adding :exclusive => true do did the trick. So now my Podfile looks like:

### Implicit target definition :-/
xcodeproj 'XXX/XXX.xcodeproj'
####
pod 'EAIntroView', '~> 2.7'

target 'XXXTests', :exclusive => true do
    pod 'OCMock', '~> 3.1'
    pod 'Specta', '~> 1.0'
    pod 'Expecta', '~> 1.0'
end