我正在测试一个 GET 端点,它应该返回 200,但它返回 404,并且响应标头也不正确。
这是日志:
Failures:
1) Verifying a pact between API Consumer and Weather API Given There is data - A GET request to retrieve the weather
1.1) has a matching body
/ -> Expected body Present(496 bytes) but was empty
1.2) has status code 200
expected 200 but was 404
1.3) includes header 'Content-Type' with value '"application/json; charset=utf-8"'
Expected header 'Content-Type' to have value '"application/json; charset=utf-8"' but was ''
There were 1 pact failures
Verifier Logs
-------------
2023-07-24T11:13:08.962868Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier: Executing provider states
2023-07-24T11:13:08.962901Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier: Running setup provider state change handler 'There is data' for 'A GET request to retrieve the weather forecasts'
2023-07-24T11:13:08.968810Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Sending HTTP Request ( method: POST, path: /, query: None, headers: Some({"Content-Type": ["application/json"]}), body: Present(54 bytes, application/json) ) to state change handler
2023-07-24T11:13:08.969055Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: reqwest::connect: starting new connection: http://localhost:7058/
2023-07-24T11:13:08.978147Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: hyper::client::connect::http: connecting to [::1]:7058
2023-07-24T11:13:08.978582Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: hyper::client::connect::http: connected to [::1]:7058
2023-07-24T11:13:09.107613Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: hyper::client::pool: pooling idle connection for ("http", localhost:7058)
2023-07-24T11:13:09.107649Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: State change request: Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(7058), path: "/provider-states", query: None, fragment: None }, status: 200, headers: {"content-length": "0", "date": "Mon, 24 Jul 2023 11:13:08 GMT", "server": "Kestrel"} }
2023-07-24T11:13:09.107736Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier: State Change: "ProviderState { name: "There is data", params: {} }" -> Ok({})
2023-07-24T11:13:09.107750Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier: Running provider verification for 'A GET request to retrieve the weather'
2023-07-24T11:13:09.107789Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier: Verifying a HTTP interaction
2023-07-24T11:13:09.107817Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Sending request to provider at http://localhost:7058/
2023-07-24T11:13:09.107818Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Provider details = ProviderInfo { name: "Weather API", protocol: "http", host: "localhost", port: Some(7058), path: "/", transports: [ProviderTransport { transport: "http", port: Some(7058), path: Some("/"), scheme: None }] }
2023-07-24T11:13:09.107829Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Sending request HTTP Request ( method: GET, path: /weather-forecast, query: None, headers: None, body: Missing )
2023-07-24T11:13:09.107831Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: body:
2023-07-24T11:13:09.107853Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: hyper::client::pool: reuse idle connection for ("http", localhost:7058)
2023-07-24T11:13:09.118997Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: hyper::client::pool: pooling idle connection for ("http", localhost:7058)
2023-07-24T11:13:09.119024Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Received native response: Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("localhost")), port: Some(7058), path: "/weather-forecast", query: None, fragment: None }, status: 404, headers: {"content-length": "0", "date": "Mon, 24 Jul 2023 11:13:08 GMT", "server": "Kestrel"} }
2023-07-24T11:13:09.119062Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: Received response: HTTP Response ( status: 404, headers: Some({"content-length": ["0"], "date": ["Mon", "24 Jul 2023 11:13:08 GMT"], "server": ["Kestrel"]}), body: Empty )
2023-07-24T11:13:09.119067Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_verifier::provider_client: body:
2023-07-24T11:13:09.119088Z INFO ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather"}: pact_matching: comparing to expected response: HTTP Response ( status: 200, headers: Some({"Content-Type": ["application/json; charset=utf-8"]}), body: Present(496 bytes) )
2023-07-24T11:13:09.119130Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather forecasts"}: pact_matching: expected content type = 'application/json;charset=utf-8', actual content type = '*/*'
2023-07-24T11:13:09.119352Z DEBUG ThreadId(01) verify_interaction{interaction="A GET request to retrieve the weather forecasts"}: pact_matching: content type header matcher = 'RuleList { rules: [], rule_logic: And, cascaded: false }'
这是我从文档中的示例中获得的代码(提供者状态确实已设置,对我来说也不是必需的,因为我们返回硬编码数据)。
public class ProviderTests : IDisposable
{
private readonly IHost server;
public Uri ServerUri { get; }
private readonly PactVerifier verifier;
public ProviderTests(ITestOutputHelper output)
{
ServerUri = new Uri("http://localhost:7058");
server = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls(ServerUri.ToString());
webBuilder.UseStartup<TestStartup>();
})
.Build();
server.Start();
this.verifier = new PactVerifier(new PactVerifierConfig
{
LogLevel = PactLogLevel.Debug,
Outputters = new List<IOutput>
{
new XunitOutput(output)
}
});
}
public void Dispose()
{
server.Dispose();
}
[Fact]
public void EnsureSomethingApiHonoursPactWithConsumer()
{
// Arrange
string pactPath = Path.Combine("..",
"..",
"..",
"..",
"ConsumerTests",
"pacts",
"API Consumer.json");
try
{
this.verifier
.ServiceProvider("Weather API", ServerUri)
.WithFileSource(new FileInfo(pactPath))
.WithProviderStateUrl(new Uri(ServerUri, "/provider-states"))
.Verify();
} catch (Exception e)
{
throw;
}
}
}
我也面临着同样的问题。检查您的 ServerUri (http://localhost:7058) 是否与托管应用程序的位置相同。您可以在 launchSettings.json 中检查它,也可以在 Program.cs 中设置端口,例如:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://localhost:7058")
.Build();
}
我已经这样做了,但仍然收到那些 404。希望我能回到这里