单元测试
- 新建 asp.net core web 工程
- 新建 xunit 工程,引用 web 工程
- 在 xunit 工程中添加包:Microsoft.AspNetCore.All。添加后如果有问题,将 csporj 文件中的 Microsoft.AspNetCore.All 版本号去掉
<PackageReference Include="Microsoft.AspNetCore.All" /><PackageReference>
- 可选择添加 Moq 库 Mock
测试用例:
public class ControllerTests
{
[Fact]
public void VerifyIndexViewType()
{
//var repository = new InMemoryProductRepository();
//var controller = new HomeController(repository);
var repository = new Mock<IProductRepository>();
var controller = new HomeController(repository.Object);
var result = controller.Index();
Assert.IsType<ViewResult>(result);
}
[Fact]
public void VerifyListProductCount()
{
var repository = new Mock<IProductRepository>();
repository.Setup(x => x.ListProducts()).Returns(
new List<Product>
{
new Product{Id="a",Name="aaa",Price = 2.5m},
new Product{Id="b",Name="bbb",Price = 3.5m}
}
);
var controller = new HomeController(repository.Object);
var result = Assert.IsType<ViewResult>(controller.List());
var model = Assert.IsType<List<Product>>(result.Model);
Assert.Equal(2, model.Count);
}
[Fact]
public void VerifyValidIdReturnsProperProduct()
{
var repository = new Mock<IProductRepository>();
repository.Setup(
x =>x
.GetRepository(It.IsInRange("aaa","bbb",Range.Inclusive))
).Returns(new Product { Id = "aaa", Name = "aaa", Price = 2.5m });
var controller = new HomeController(repository.Object);
var result = Assert.IsType<ViewResult>(controller.Detail("aaa"));
var model = Assert.IsType<Product>(result.Model);
Assert.Equal("aaa", model.Name);
}
[Fact]
public void VerifyInValidIdReturnsProperProduct()
{
var repository = new Mock<IProductRepository>();
repository.Setup(
x => x
.GetRepository(It.IsInRange("ccc", "ddd", Range.Inclusive))
).Returns((Product)null);
var controller = new HomeController(repository.Object);
var result = Assert.IsType<ViewResult>(controller.Detail("ccc"));
Assert.Null(result.Model);
}
}
集成测试 参考
- 添加 Microsoft.AspNetCore.TestHost
- 建立 CientProvider 类以方便测试:
public class ClientProvider:IDisposable
{
private TestServer _server;
public HttpClient Client { get; private set; }
public ClientProvider()
{
_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
Client = _server.CreateClient();
}
public void Dispose()
{
_server?.Dispose();
Client?.Dispose();
}
}
待测试的 Controller:
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
List<Employee> employees = new List<Employee>();
[HttpGet]
public ActionResult GetAll()
{
return Ok(new Employee { Id = 1, Name = "asd" });
}
[HttpPost]
public ActionResult<List<Employee>> Add(Employee employee)
{
employees.Add(employee);
return Ok(employees);
}
}
测试类写法:
public class EmployeeApiIntergrationTests
{
[Fact]
public async Task Test_GetAll()
{
using (var client = new ClientProvider().Client)
{
var response = await client.GetAsync("/api/employee");
response.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
}
}
- 添加 FluentAssertions库 快速断言
[Fact]
public async Task Test_GetAll()
{
using (var client = new ClientProvider().Client)
{
var response = await client.GetAsync("/api/employee");
response.EnsureSuccessStatusCode();
response.StatusCode.Should().Be(HttpStatusCode.OK);
}
}
- Post 测试:
[Fact]
public async Task Test_Post()
{
using (var client = new ClientProvider().Client)
{
var employee = new Employee { Id = 2, Name = "abc" };
var postContent = JsonConvert.SerializeObject(employee);
var response = await client.PostAsync(
"/api/employee",
new StringContent(postContent,Encoding.UTF8,"application/json")
);
response.EnsureSuccessStatusCode();
response.StatusCode.Should().Be(HttpStatusCode.OK);
var responseContent =await response.Content.ReadAsAsync<List<Employee>>();
responseContent.Count.Should().Be(1);
}
}
测试项目packages:
image.png
网友评论