Accessing Bundle of main application while running XCTests
Added file to 'Copy Bundle Resources' of Test target also, then used following code to get path for resource , instead of "\(Bundle.main.resourcePath!)/test.command"
let testBundle = Bundle(for: type(of: self))
let path = "\(testBundle.resourcePath!)/test.command""
NSURL to file path in test bundle with XCTest
In fact, the [NSBundle mainBundle]
when running a UnitTest is not the path of your app, but is /Developer/usr/bin, so this will not work.
The way to get resources in a unit test is here: OCUnit & NSBundle
In short, use:
[[NSBundle bundleForClass:[self class]] resourcePath]
or in your case:
[[NSBundle bundleForClass:[self class]] resourceURL]
Why can't code inside unit tests find bundle resources?
When the unit test harness runs your code, your unit test bundle is NOT the main bundle.
Even though you are running tests, not your application, your application bundle is still the main bundle. (Presumably, this prevents the code you are testing from searching the wrong bundle.) Thus, if you add a resource file to the unit test bundle, you won't find it if search the main bundle. If you replace the above line with:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:@"foo" ofType:@"txt"];
Then your code will search the bundle that your unit test class is in, and everything will be fine.
XCTest fails when calling [NSBundle mainBundle]
The simplest and cleanest way of fixing this issue is to partially mock the NSBundle class in your unit tests to return [NSBundle bundleForClass:[self class]]
when you call [NSBundle mainBundle]
.
You may put this in your -setup
method so that it is mocked for your entire test class:
static id _mockNSBundle;
@implementation MyTests
- (void)setUp
{
[super setUp];
_mockNSBundle = [OCMockObject niceMockForClass:[NSBundle class]];
NSBundle *correctMainBundle = [NSBundle bundleForClass:self.class];
[[[[_mockNSBundle stub] classMethod] andReturn:correctMainBundle] mainBundle];
}
@end
Nice and clean.
[Source]
XCode 5 unit testing: starts my app
You are running application test, not logic test. This means an instance of your app will be started and then run the unit tests. This allow you to perform some integration test that require your app is running.
Here is the guide to setup application test and logic test.
If you want to change it to logic test (so it run faster and don't need to start your app first):
- go to build settings for your unit test target
- search
Bundle
- remove Bundle Loader and Test Host
Related Topics
How to Create a Single Page Vertical Scrolling Pdfview in Swift
How to Specify Japanese Encoding for a UIlabel
Swift Lose Precision in Decimal Formatting
Lsapplicationqueriesschemes and Derived Data
Convert from Nsdictionary to [String:Any]
How to Observe Object's Property in Rxswift
Xcode 9.2 Is Not Showing Swift 4.1
Scenekit - Why Scnlight Created Automatically in Scnscene
How to Split a String at The Last Occurence of a Sequence
Rxswift: Ondisposed Activated Before Alamofire Return Data
How to Cast Sockaddr_In to Sockaddr in Swift
Swift Combine How Set<Anycancellable> Works
Destructuring Tuple of Tuple in Closure
Member Operator '==' Must Have at Least One Argument of Type