Mockingjay icon indicating copy to clipboard operation
Mockingjay copied to clipboard

Matcher doesn't match partly URLs

Open Buju77 opened this issue 7 years ago • 3 comments

It seems current version (2.0.1) of matcher doesn't match uri path partly.

Example:

func testPartlyPathMatches() {
    let request = URLRequest(url: URL(string: "https://api.palaverapp.com/some/other/v42/auth/login")!)
    XCTAssertTrue(uri("/auth/login")(request))
}

This test will fail. It seems I always need to specify everything after the host in the uri matcher. This is a bit inconvenient.

Because eg. I as mobile app developer don't want to care how the backend has structured the login endpoint in my tests or which endpoint version it is. I'm only interested in stubbing the login request.

Or did I miss something?

Buju77 avatar Apr 20 '18 13:04 Buju77

It seems current version (2.0.1) of matcher doesn't match uri path partly.

That is intentional, it is designed to be the full URI of full path.

Try the following:

func isLogin(_ request: URLRequest) -> Bool {
  return request.url?.path.hasSuffix("/auth/login") ?? false
}

stub(isLogin, failure(error))

kylef avatar Apr 20 '18 18:04 kylef

thx. your suggested solution works, but not very intuitive on first sight. can you please elaborate more on the design decision of only matching full URIs instead of only partly matching?

Buju77 avatar Apr 23 '18 09:04 Buju77

I also noticed that it really needs to match the full URI including query parameters, which is very cumbersome in my case. The requests I want to simply mock have lots of query parameters.

My use case: I want to write integration tests of my whole system. I want to test if our backend sends us a specific error code like 410 with some response body. So in those error case tests, I don't really care about any of those query parameters.

So my workaround is creating this new matcher to partly match the uri

func partUri(_ uri: String) -> (_ request: URLRequest) -> Bool {
    return { (_ request: URLRequest) in
        return request.url?.path.contains(uri) ?? false
    }
}

and then

    let jsonString = """ ... """
    let data = jsonString.data(using: .utf8)!
    stub(partUri("/samples"), jsonData(data, status: 410))

I believe a mocking library should offer a built-in possibility to mock network requests in a very easy and very fast way. This includes only matching part of uri.

eg. instead of using the regex pattern "^\(pattern)$", simply use "\(pattern)" in URITemplate.swift. Maybe add some flags to turn it on/off.

Buju77 avatar Apr 26 '18 08:04 Buju77