Since Xcode 10.1(maybe 10) when I create a Unit test file I don't have calls super.tearDown() and super.setUp() .
I've not seen such changes in release notes.
In documentation https://developer.apple.com/documentation/xctest/xctestcase/understanding_setup_and_teardown_for_test_methods are still here.
So my question should I still write super.tearDown() and super.setUp()?
class SomethingTests: XCTestCase {
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
For a direct subclass of XCTestCase, there never was any change of behavior for not calling super.setUp(). That's because setUp and tearDown are template methods with empty implementations at the top level.
Though there's no change in behavior, omitting the calls to super means that if you create a test hierarchy with more than one level, you'll have to add them back.
When would you ever have more than one level? There are two cases:
When you want to reuse the same tests for different scenarios.
When you subclass XCTestCase to make a customized helper.
These don't happen every day. But they do happen. Deciding "I need it here, but I don't need it there" is perilous. So I'd just call super all the time.
Related
I want an embedded view to be able to call a function from the parent view, so I'm trying to have the child reference its parent by injection. This seems to work fine as long as the embedded view is created onDock:
class TestView : View() {
override val root = vbox {
label("Parent Label")
}
init {
println("Parent is instantiating.")
}
override fun onDock() {
val child = find(TestView2::class)
root.add(child)
}
fun doThing() {
println("Parent is doing a thing.")
}
}
class TestView2 : View() {
val parentClass: TestView by inject()
override val root = hbox {
label("Sub-view label 1")
label("Sub-view label 2")
}
init {
println("Sub-view is instantiating.")
parentClass.doThing()
}
}
I'd like it to be cleaner though. I'd prefer it if I was able to use the find function while creating the parent root. That's a problem, as calling the child view within any part of the init process creates a circular instantiation loop. Any way to avoid this or will I just have to settle for onDock and deal with it?
EDIT:
Just to note, I tried the onDock method again in a real, more complicated application and I got a cycle detection error. So even that method is not guaranteed to work.
You can create cyclic dependencies, but you can't call functions in both component's init block, as that would be impossible to resolve. The main takeaway here is that you're probably doing something you shouldn't. Views should not communicate with each other directly. This creates a tight coupling and prevents reuse. Instead you should communicate with one of the following:
State from a ViewModel
Controller function calls
Events using the EventBus
Since your code example is made up, it's not known what exactly you're trying to achieve in your actual app, but you will find the correct approach in the list above.
I see the urge to call functions in views and setting data directly into ui components instead of using bindings a lot, and in absolutely every case there is a much better way to solve the problem :)
I'm trying to write a Jasmine test for a function of class which instantiates and observes an object from another class. Since I want to keep this test contained to the first class and to simulate different scenarios of the second I want to mock the second. Some pseudo code might help
export class Foo {
startProcessing() {
const bar = new Bar();
const sub = bar.tickTock.subscribe(
state => {
// something went right
},
error => {
// something went wrong
}
);
}
}
I've tried declaring the mock class in my test file, and providing it through TestBed.configureTestingModule's providers attribute, but it always uses the original Bar.
How can I write a test that provides a mock class in place of Bar that I can control?
One way to get around this issue is to pass in object of type Bar through function parameter (dependency injection). That way you can have control over Bar object.
I need the test status after each test case is executed in my test suite in Xcode. I know an observer can help in achieving it. But how do I use it in my tests?
You are on the right track and can achieve what you're wanting to do via the XCTestObservation protocol (https://developer.apple.com/documentation/xctest/xctestobservation). You can add an observer to your test case class and I'd recommend doing this in the setUp() method since it gets executed before each test method.
override func setUp() {
super.setUp()
continueAfterFailure = false
XCUIApplication().launch()
XCTestObservationCenter.shared.addTestObserver(UITestObserver())
}
To do this you should implement a class that conforms to the XCTestObservation protocol and then provide your own implementation to the methods of interest to perform whatever actions you need/want. In your case you're probably going to want to provide an implementation for this method...
optional public func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int)
Here's a quick example of what this test observer class might look like...
import XCTest
public class UITestObserver: NSObject, XCTestObservation {
public func testCase(_ testCase: XCTestCase,
didFailWithDescription description: String,
inFile filePath: String?,
atLine lineNumber: Int) {
print("failure description: \(description)")
print("failed test case: \(testCase)")
if let filePath = filePath {
print("failure at file path: \(filePath)")
}
print("failure at line: \(lineNumber)")
}
}
This function I provided an example of above gets called whenever one of your test cases fails, so you don't need to "do" anything from within your test case class or methods.
Hope this helps!
The result of each test case executed is saved on a file named ***TestSummeries.plist.
You will find it under
~/Library/Developer/Xcode/DerivedData/<your-app-name>/Logs/Test/****_TestSummeries.plist
If you run your test many times just delete the everything inside DerivedData before execution. Then you will find only one TestSummeries.plist.
Then parse the plist and get your desired data from the plist file.
** If you need more information about it feel free to comment below.
I am testing the following method with OCMock:
- (void)methodToTest {
[self.someObject doFirstActionWithParam:#"aparam" completion:(void(^)(BOOL success)) {
if (success) {
[self.someObject doSecondActionWithParam:#"aparam" completion:(void(^)(BOOL success)) {
if (success) { [self doSomething]; }
}];
}
}];
}
I have a partial mock for self.someObject.
The doFirstActionWithParam, I am able to set an expectation for. I am also overriding the completion block (via NSInvocation and invoking a YES completion).
However, I am not able to get the call for doSecondActionWithParam method. I also set up expectation for doSomething method. That never comes through.
Any suggestion for an approach to test nested completion blocks?
There shouldn't be a difference due to the nesting level when you mock a method (stub or expect). As you didn't include your test code it's really difficult to diagnose the problem. My assumption is that the block that is passed to doFirstActionWithParam:completion: is never invoked, in which case doSecondActionWithParam:completion: would als never be invoked.
I've created a significant number of methods to help me perform unit test assertions in Visual Studio 2010. I've also enabled "Double-click a Failed or Inconclusive unit test result displays the point of failure in the test" option in the Test Execution options. My issue is that with these helper methods, I'd like the point of failure to be the stack frame calling my helper method, not the exception being thrown within the helper method.
Obviously, I can do "ShowDetails" and click higher in the stack, but that will pretty much cancel out any time saved by using the helper method.
I've tried using the various [Debugger*] attributes on my method without success.
Here's some example code to illustrate my issue.
public void MyTest()
{
// ACT
var res = DoSomething();
// ASSERT
AssertDateRange(res, TimeSpan.FromDays(7));
}
public static void AssertDateRange(DateTime value, TimeSpan range)
{
var difference = DateTime.Now.Subtract(value);
if (Math.Abs(range.TotalMilliseconds) - Math.Abs(difference.TotalMilliseconds) < 0)
{
throw new AssertFailedException("DateTime was not within the expected range from now.");
}
}
I'd like for the double-click to place me on the method call within the MyTest method, while it now places me on the throw within the AssertDateRange method.