You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FakeItEasy对WebApi控制器执行集成测试?

Guide to Polishing Your CustomersController Integration Tests

Hey there! Since you're new to integration testing, let's go through how to refine your current test setup and make it more robust, maintainable, and reliable—all based on the code snippets you shared.

1. Fix Configuration Management (No More Hardcoded Values!)

Right now you've got hardcoded URLs, usernames, and passwords in your test setup. That's not ideal for security or flexibility. Instead, use a configuration file (like appsettings.test.json) to store these values:

First, add an appsettings.test.json file to your test project (set "Copy to Output Directory" to "Copy if newer"):

{
  "ApiSettings": {
    "BaseAddress": "https://mywebaaplication.com",
    "Username": "your-test-username",
    "Password": "your-test-password",
    "AzureAd": {
      "TenantId": "your-tenant-id",
      "ClientId": "your-client-id",
      "ClientSecret": "your-client-secret"
    }
  }
}

Then update your Setup method to load this configuration:

using Microsoft.Extensions.Configuration;

[SetUp]
public void Setup()
{
    var config = new ConfigurationBuilder()
        .AddJsonFile("appsettings.test.json")
        .Build();

    _baseAddress = config["ApiSettings:BaseAddress"];
    _username = config["ApiSettings:Username"];
    _password = config["ApiSettings:Password"];

    // Initialize AzureAD handler with config values
    var azureAdConfig = config.GetSection("ApiSettings:AzureAd");
    var authHandler = new AzureADApiClientAuthenticationHandler(
        azureAdConfig["TenantId"],
        azureAdConfig["ClientId"],
        azureAdConfig["ClientSecret"]
    );

    _apiClient = new ApiClient(authHandler, _baseAddress);
}

2. Fix Test Data & Type Mismatch

In your test, you're passing customerType = 500 (an integer) but your API expects a string parameter. That'll cause a bad request! Also, using an empty customerNumber won't return meaningful results. Instead, use known test data—either pre-seed your test database with a test customer, or use a test factory to create one before the test runs.

Here's an updated test method with valid, meaningful data:

[Test]
public async Task CustomersController_GetCustomer_ReturnsExpectedCustomer()
{
    // Arrange: Pre-seed test data (use your data context or a setup script)
    var testCustomerNumber = "TEST-123";
    var testCustomerType = "500"; // Match the string type expected by the API

    // Act
    var result = await _apiClient.GetAsync<Customer[]>($"/api/customers/GetCustomer?customerNumber={testCustomerNumber}&customerType={testCustomerType}");

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(1, result.Length); // Expect exactly one customer for our test data
    Assert.AreEqual(testCustomerNumber, result[0].CustomerNumber); // Verify the correct customer is returned
    Assert.AreEqual(testCustomerType, result[0].CustomerType);
}

3. Ensure Test Isolation

Integration tests should run independently—one test shouldn't affect another. To do this:

  • Use a dedicated test database (not your production or dev DB)
  • Reset the database state before each test:
    • Use a tool like Respawn to truncate tables
    • Wrap tests in a transaction that rolls back after execution
    • Seed fresh test data in the SetUp method and clean it up in TearDown

Example with transaction rollback (if using EF Core):

private IDbContextTransaction _transaction;
private YourDataContext _testDbContext;

[SetUp]
public void Setup()
{
    // ... existing config setup ...

    // Initialize test DB context
    _testDbContext = new YourDataContext();
    _transaction = _testDbContext.Database.BeginTransaction();

    // Seed test customer
    _testDbContext.Customers.Add(new Customer
    {
        CustomerNumber = "TEST-123",
        CustomerType = "500",
        // Set other required properties
    });
    _testDbContext.SaveChanges();
}

[TearDown]
public void TearDown()
{
    _transaction.Rollback(); // Undo all changes from the test
    _transaction.Dispose();
    _testDbContext.Dispose();
}

4. Test Error Scenarios

Don't just test the happy path! Add tests for edge cases and errors:

  • Invalid customerNumber (should return empty array or 404)
  • Missing required parameters (should return 400 Bad Request)
  • Unauthenticated request (should return 401 Unauthorized)

Example of an error scenario test:

[Test]
public async Task CustomersController_GetCustomer_InvalidNumber_ReturnsEmptyArray()
{
    // Act
    var result = await _apiClient.GetAsync<Customer[]>($"/api/customers/GetCustomer?customerNumber=INVALID-999&customerType=500");

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(0, result.Length);
}

5. Improve API Client Usage

Instead of concatenating query strings manually (which can lead to encoding issues), use HttpClient's QueryHelpers to build the request URL safely:

using System.Net.Http;

var queryParams = new Dictionary<string, string>
{
    { "customerNumber", testCustomerNumber },
    { "customerType", testCustomerType }
};
var requestUrl = QueryHelpers.AddQueryString("/api/customers/GetCustomer", queryParams);
var result = await _apiClient.GetAsync<Customer[]>(requestUrl);

内容的提问来源于stack exchange,提问作者Ravikumar Patil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:21:48