I'm new in the unit testing.
and I had an issue about asynchronous function testing.
func test_Repository()
{
let properEmail = ""
let properPassword = ""
let improperEmail = ""
let improperPassword = ""
let testArray = [(username : "", password : ""), // both empty
(username : "", password : properPassword), // empty email
(username : properEmail, password : ""), // empty password
(username : improperEmail, password : properPassword), // wrong email
(username : properEmail, password : improperPassword) // wrong password
]
let repo = UserRepository()
let exp =
expectation(description: "Wait for async signIn to complete")
for data in testArray
{
print(data.username)
print(data.password)
repo.createNewUser(data.username, password: data.password) {[weak self] email, error in
XCTAssertNotNil(error)
exp.fulfill()
}
sleep(5)
}
wait(for: [exp], timeout: 200.0)
}
as you can see, I want to test all improve possibilities but it didn't work.
and also my asynchronous create function is here
func createNewUser(_ email : String, password : String,result: @escaping (_ email : String, _ error : Error?)->())
{
auth.createUser(withEmail: email, password: password) { [weak self] authResult, error in
if let error = error
{
self?.userCreationError = true
self?.userCreationErrorText = error.localizedDescription
result("",error)
}
else
{
if let authresult = authResult
{
self?.user.email = authresult.user.email ?? ""
self?.createNewUserTable(user: self!.user)
result((self?.user.email)!,nil)
}
}
}
}
CodePudding user response:
You would need to create the expectation for every iteration. For now you code continues after the first itteration.
// add the expectation to your data tuple
let testArray = [(username : "", password : "", expectation: expectation("description")), // both empty // expand this example to all testcases
(username : "", password : properPassword), // empty email
(username : properEmail, password : ""), // empty password
(username : improperEmail, password : properPassword), // wrong email
(username : properEmail, password : improperPassword) // wrong password
]
for data in testArray
{
print(data.username)
print(data.password)
repo.createNewUser(data.username, password: data.password) {[weak self] email, error in
XCTAssertNotNil(error)
//fulfill the associated expectation
data.expectation.fulfill()
}
sleep(5)
}
//wait for all expectations
wait(for: [testArray.map{$0.expectation}], timeout: 200.0)
CodePudding user response:
Your test was probably left "early", since your expectation was fulfilled after the first completion and the test then stopped.
You need to tell your expectation that it should be considered completed only after all elements in your test array have called fulfill()
:
let exp = expectation(description: "Wait for async signIn to complete")
exp.expectedFulfillmentCount = testArray.count
A different approach, which serializes the tests and is going to run faster, would be to create an expectation for each iteration and wait for it:
for data in testArray
{
print(data.username)
print(data.password)
let exp = expectation(description: "…")
repo.createNewUser(data.username, password: data.password) {[weak self] email, error in
XCTAssertNotNil(error)
exp.fulfill()
}
wait(for: [exp], timeout: 5)
}