UnitTest中的所有获取实体对象改为使用AutoFixture
CountriesServiceTest.cs
using AutoFixture;
using Entities;
using EntityFrameworkCoreMock;
using Microsoft.EntityFrameworkCore;
using ServiceContracts;
using ServiceContracts.DTO;
using Services;
using System;
using System.Collections.Generic;
namespace CRUDxUnitTests
{
public class CountriesServiceTest
{
private readonly ICountriesService _countriesService;
private readonly IFixture _fixture;
public CountriesServiceTest()
{
var countriesInitialData = new List<Country>() { };
DbContextMock<ApplicationDbContext> dbContextMock =
new DbContextMock<ApplicationDbContext>(new DbContextOptionsBuilder<ApplicationDbContext>().Options);
ApplicationDbContext dbContext = dbContextMock.Object;
dbContextMock.CreateDbSetMock(c => c.Countries,countriesInitialData);
_countriesService = new CountriesService(dbContext);
_fixture = new Fixture();
}
#region AddCountry
//When CountryAddRequest is null, it should throw ArgumentNullException
[Fact]
public async Task AddCountry_NullCountry()
{
//Arrange
CountryAddRequest? request = null;
//Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
//Act
await _countriesService.AddCountry(request);
});
}
//When the CountryName is null , it should throw ArgumentException
[Fact]
public async Task AddCountry_CountryNameIsNull()
{
//Arrange
CountryAddRequest request = new CountryAddRequest()
{
CountryName = null
};
//Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
//Act
await _countriesService.AddCountry(request);
});
}
//When the CountryName is duplicate, it should throw ArgumentException
[Fact]
public async Task AddCountry_DuplicateCountryName()
{
//Arrange
CountryAddRequest request1 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
CountryAddRequest request2 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
//Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
//Act
await _countriesService.AddCountry(request1);
await _countriesService.AddCountry(request2);
});
}
//When you supply proper country name, it should inset (add) the country to the existing list of countries
[Fact]
public async Task AddCountry_ProperCountryName()
{
//Arrange
CountryAddRequest request = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "ChaoXian").Create();
//Act
CountryResponse countryResponse = await _countriesService.AddCountry(request);
List<CountryResponse> countryResponseFromGetAllCountries = await _countriesService.GetAllCountries();
//Assert
Assert.True(countryResponse.CountryId != Guid.Empty);
Assert.Contains(countryResponse, countryResponseFromGetAllCountries);
//Assert.Contains比较的时候使用了objA.Equals(objB),是引用类型的比较,不是值的比较
//所以需要在CountryResponse类中重写Equals
}
#endregion
#region GetAllCountries
//The list of countries should be empty by default(before adding any countries)
[Fact]
public async Task GetAllCountries_EmptyList()
{
//Acts
List<CountryResponse> countryResponsesList = await _countriesService.GetAllCountries();
//Assert
Assert.Empty(countryResponsesList);
}
//judge if less countries is added
[Fact]
public async Task GetAllCountries_AddFewCountries()
{
//Arrange
List<CountryAddRequest> countryAddRequestList = new List<CountryAddRequest>()
{
_fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create(),
_fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "UK").Create()
};
//Act
List<CountryResponse> countryResponseLsit = new List<CountryResponse>();
foreach (CountryAddRequest item in countryAddRequestList)
{
countryResponseLsit.Add(await _countriesService.AddCountry(item));
}
List<CountryResponse> actualCountryResponseList = await _countriesService.GetAllCountries();
//Assert
//read each element from countryResponseLsit
foreach (CountryResponse expected_country in countryResponseLsit)
{
Assert.Contains(expected_country, actualCountryResponseList);
}
}
#endregion
#region GetCountryByCountryId
//If we supply null as CountryId, it should return null as CountryResponse
[Fact]
public async Task GetCountryByCountryId_NullCountryId()
{
//Arrange
Guid? countryId = null;
//Act
CountryResponse? countryResponse = await _countriesService.GetCountryByCountryId(countryId);
//Assert
Assert.Null(countryResponse);
}
//If we supply a valid country id, it should return the matching country details as CountryResponse object
[Fact]
public async Task GetCountryByCountryId_ValidCountryId()
{
//Arrange
CountryAddRequest? countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "China").Create();
CountryResponse? countryResponseAdd = await _countriesService.AddCountry(countryAddRequest);
//Act
CountryResponse? countryResponseGet = await _countriesService.GetCountryByCountryId(countryResponseAdd.CountryId);
//Assert
Assert.Equal(countryResponseAdd, countryResponseGet);
}
#endregion
}
}
PersonsServiceTest.cs
using AutoFixture;
using Entities;
using EntityFrameworkCoreMock;
using Microsoft.EntityFrameworkCore;
using ServiceContracts;
using ServiceContracts.DTO;
using ServiceContracts.Enums;
using Services;
using System;
using System.Collections.Generic;
using Xunit.Abstractions;
namespace CRUDxUnitTests
{
public class PersonsServiceTest
{
//private fields
private readonly IPersonsService _personService;
private readonly ICountriesService _countriesService;
private readonly ITestOutputHelper _testOutputHelper;
private readonly IFixture _fixture;
//constructor
public PersonsServiceTest(ITestOutputHelper testOutputHelper)
{
var countriesInitialData = new List<Country>() { };
var personsInitialData = new List<Person>() { };
DbContextMock<ApplicationDbContext> dbContextMock =
new DbContextMock<ApplicationDbContext>(new DbContextOptionsBuilder<ApplicationDbContext>().Options);
ApplicationDbContext dbContext = dbContextMock.Object;
dbContextMock.CreateDbSetMock(c => c.Countries, countriesInitialData);
dbContextMock.CreateDbSetMock(p => p.Persons, personsInitialData);
_countriesService = new CountriesService(dbContext);
_personService = new PersonsService(dbContext, _countriesService);
_testOutputHelper = testOutputHelper;
_fixture = new Fixture();
}
#region AddPerson
//When we supply null value as PersonAddRequest, it should throw ArgumentNullException
[Fact]
public async Task AddPerson_NullPerson()
{
//Arrange
PersonAddRequest? personAddRequest = null;
//Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
//Act
await _personService.AddPerson(personAddRequest);
});
}
//When we supply null value as PersonName, it should throw ArgumentNullException
[Fact]
public async Task AddPerson_PersonNameIsNull()
{
//Arrange
PersonAddRequest? personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, null as string).Create();
//Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
//Act
await _personService.AddPerson(personAddRequest);
});
}
//When we supply proper person details, it should insert the person into the persons list
//and it should return an object of PersonResponse, which includes with the newly generated person id
[Fact]
public async Task AddPerson_ProperPersonDetails()
{
//Arrange
//PersonAddRequest? personAddRequest = _fixture.Create<PersonAddRequest>();
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.Email, "person@example.com").Create();
//Act
PersonResponse personResponse = await _personService.AddPerson(personAddRequest);
List<PersonResponse> personResponses = await _personService.GetAllPersons();
//Assert
Assert.True(personResponse.PersonId != Guid.Empty);
Assert.Contains(personResponse, personResponses);
}
#endregion
#region GetPersonByPersonId
//If we supply null as PersonId, it should return null as PersonResponse
[Fact]
public async Task GetPersonByPersonId_NullPersonId()
{
//Arrange
Guid? personId = null;
//Act
PersonResponse? personResponse = await _personService.GetPersonByPersonId(personId);
//Assert
Assert.Null(personResponse);
}
//If we supply a valid person id, it should return thr valid person details as PersonResponse object
[Fact]
public async Task GetPersonByPersonId_ValidPersonId()
{
//Arrange
CountryAddRequest countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "Canada").Create();
CountryResponse countryResponse = await _countriesService.AddCountry(countryAddRequest);
//Act
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.Email, "email@example.com").Create();
PersonResponse personResponseAdd = await _personService.AddPerson(personAddRequest);
PersonResponse? personResponseGet = await _personService.GetPersonByPersonId(personResponseAdd.PersonId);
//Assert
Assert.Equal(personResponseAdd, personResponseGet);
}
#endregion
#region GetAllPersons
//The GetAllPersons() should return an empty list by default
[Fact]
public async Task GetAllPersons_EmptyList()
{
//Act
List<PersonResponse> personResponses = await _personService.GetAllPersons();
//Assert
Assert.Empty(personResponses);
}
//First, we will add few persons, and then when we call GetAllPersons(), it should return the sample persons that were added
[Fact]
public async Task GetPersons_AddFewPersons()
{
//Arrange
CountryAddRequest countryAddRequest1 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
CountryAddRequest countryAddRequest2 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "India").Create();
CountryResponse countryResponse1 = await _countriesService.AddCountry(countryAddRequest1);
CountryResponse countryResponse2 = await _countriesService.AddCountry(countryAddRequest2);
PersonAddRequest personAddRequest1 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Smith")
.With(p => p.Email, "smith@example.com")
.Create();
PersonAddRequest personAddRequest2 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Marry")
.With(p => p.Email, "marry@example.com")
.Create();
PersonAddRequest personAddRequest3 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Rahman")
.With(p => p.Email, "rahman@example.com")
.Create();
List<PersonAddRequest> personAddRequests = new List<PersonAddRequest>()
{
personAddRequest1, personAddRequest2, personAddRequest3
};
List<PersonResponse> personResponsesAdd = new List<PersonResponse>();
foreach (PersonAddRequest request in personAddRequests)
{
PersonResponse personResponse = await _personService.AddPerson(request);
personResponsesAdd.Add(personResponse);
}
//print personResponsesAdd
_testOutputHelper.WriteLine("Expected:");
foreach (PersonResponse item in personResponsesAdd)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Act
List<PersonResponse> personResponsesGet = await _personService.GetAllPersons();
//print personResponsesGet
_testOutputHelper.WriteLine("Actual:");
foreach (PersonResponse item in personResponsesGet)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Assert
foreach (PersonResponse personResponseAdd in personResponsesAdd)
{
Assert.Contains(personResponseAdd, personResponsesGet);
}
}
#endregion
#region GetFilteredPersons
//If the search text is empty and search by is "PersonName", it should return all persons
[Fact]
public async Task GetFilteredPersons_EmptySearchText()
{
//Arrange
CountryAddRequest countryAddRequest1 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
CountryAddRequest countryAddRequest2 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "India").Create();
CountryResponse countryResponse1 = await _countriesService.AddCountry(countryAddRequest1);
CountryResponse countryResponse2 = await _countriesService.AddCountry(countryAddRequest2);
PersonAddRequest personAddRequest1 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Smith")
.With(p => p.Email, "smith@example.com")
.Create();
PersonAddRequest personAddRequest2 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Marry")
.With(p => p.Email, "marry@example.com")
.Create();
PersonAddRequest personAddRequest3 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Rahman")
.With(p => p.Email, "rahman@example.com")
.Create();
List<PersonAddRequest> personAddRequests = new List<PersonAddRequest>()
{
personAddRequest1, personAddRequest2, personAddRequest3
};
List<PersonResponse> personResponsesAdd = new List<PersonResponse>();
foreach (PersonAddRequest request in personAddRequests)
{
PersonResponse personResponse = await _personService.AddPerson(request);
personResponsesAdd.Add(personResponse);
}
//print personResponsesAdd
_testOutputHelper.WriteLine("Expected:");
foreach (PersonResponse item in personResponsesAdd)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Act
List<PersonResponse> personResponsesSearch =
await _personService.GetFilteredPersons(nameof(Person.PersonName), "");
//print personResponsesGet
_testOutputHelper.WriteLine("Actual:");
foreach (PersonResponse item in personResponsesSearch)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Assert
foreach (PersonResponse personResponseAdd in personResponsesAdd)
{
Assert.Contains(personResponseAdd, personResponsesSearch);
}
}
//First we will add few persons, and then we will search based on person name with some search string.
//It should return the matching persons
[Fact]
public async Task GetFilteredPersons_SearchByPersonName()
{
//Arrange
CountryAddRequest countryAddRequest1 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
CountryAddRequest countryAddRequest2 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "India").Create();
CountryResponse countryResponse1 = await _countriesService.AddCountry(countryAddRequest1);
CountryResponse countryResponse2 = await _countriesService.AddCountry(countryAddRequest2);
PersonAddRequest personAddRequest1 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Smith")
.With(p => p.Email, "smith@example.com")
.With(p => p.CountryId, countryResponse1.CountryId)
.Create();
PersonAddRequest personAddRequest2 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Marry")
.With(p => p.Email, "marry@example.com")
.With(p => p.CountryId, countryResponse1.CountryId)
.Create();
PersonAddRequest personAddRequest3 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Rahman")
.With(p => p.Email, "rahman@example.com")
.With(p => p.CountryId, countryResponse2.CountryId)
.Create();
List<PersonAddRequest> personAddRequests = new List<PersonAddRequest>()
{
personAddRequest1, personAddRequest2, personAddRequest3
};
List<PersonResponse> personResponsesAdd = new List<PersonResponse>();
foreach (PersonAddRequest request in personAddRequests)
{
PersonResponse personResponse = await _personService.AddPerson(request);
personResponsesAdd.Add(personResponse);
}
//print personResponsesAdd
_testOutputHelper.WriteLine("Expected:");
foreach (PersonResponse item in personResponsesAdd)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Act
List<PersonResponse> personResponsesSearch =
await _personService.GetFilteredPersons(nameof(Person.PersonName), "ma");
//print personResponsesGet
_testOutputHelper.WriteLine("Actual:");
foreach (PersonResponse item in personResponsesSearch)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Assert
foreach (PersonResponse personResponseAdd in personResponsesAdd)
{
if (personResponseAdd.PersonName != null)
{
if (personResponseAdd.PersonName.Contains("ma", StringComparison.OrdinalIgnoreCase))
{
Assert.Contains(personResponseAdd, personResponsesSearch);
}
}
}
}
#endregion
#region GetSortedPersons
//When we sort based on PersonName in DESC, it should return persons list in descending on PersonName
[Fact]
public async Task GetSortedPersons()
{
//Arrange
CountryAddRequest countryAddRequest1 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "USA").Create();
CountryAddRequest countryAddRequest2 = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "India").Create();
CountryResponse countryResponse1 = await _countriesService.AddCountry(countryAddRequest1);
CountryResponse countryResponse2 = await _countriesService.AddCountry(countryAddRequest2);
PersonAddRequest personAddRequest1 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Smith")
.With(p => p.Email, "smith@example.com")
.With(p => p.CountryId, countryResponse1.CountryId)
.Create();
PersonAddRequest personAddRequest2 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Marry")
.With(p => p.Email, "marry@example.com")
.With(p => p.CountryId, countryResponse1.CountryId)
.Create();
PersonAddRequest personAddRequest3 = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "Rahman")
.With(p => p.Email, "rahman@example.com")
.With(p => p.CountryId, countryResponse2.CountryId)
.Create();
List<PersonAddRequest> personAddRequests = new List<PersonAddRequest>()
{
personAddRequest1, personAddRequest2, personAddRequest3
};
List<PersonResponse> personResponsesAdd = new List<PersonResponse>();
foreach (PersonAddRequest request in personAddRequests)
{
PersonResponse personResponse = await _personService.AddPerson(request);
personResponsesAdd.Add(personResponse);
}
//Act
List<PersonResponse> allPersons = await _personService.GetAllPersons();
List<PersonResponse> personResponsesSort =
await _personService.GetSortedPersons(allPersons,
nameof(Person.PersonName), SortOrderOptions.DESC);
personResponsesAdd = personResponsesAdd.OrderByDescending(p => p.PersonName).ToList();
//print personResponsesAdd
_testOutputHelper.WriteLine("Expected:");
foreach (PersonResponse item in personResponsesAdd)
{
_testOutputHelper.WriteLine(item.ToString());
}
//print personResponsesGet
_testOutputHelper.WriteLine("Actual:");
foreach (PersonResponse item in personResponsesSort)
{
_testOutputHelper.WriteLine(item.ToString());
}
//Assert
for (int i = 0; i < personResponsesAdd.Count; i++)
{
Assert.Equal(personResponsesAdd[i], personResponsesSort[i]);
}
}
#endregion
#region UpdatePerson
//When we supply null as PersonUpdateRequest, it should throw ArgumentNullException
[Fact]
public async Task UpdatePerson_NullPerson()
{
//Arrange
PersonUpdateRequest? personUpdateRequest = null;
//Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
//Act
await _personService.UpdatePerson(personUpdateRequest);
});
}
//When we supply invalid person id, it should throw ArgumentNullException
[Fact]
public async Task UpdatePerson_InvalidPersonId()
{
//Arrange
PersonUpdateRequest? personUpdateRequest = _fixture.Build<PersonUpdateRequest>()
.Create();
//Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
//Act
await _personService.UpdatePerson(personUpdateRequest);
});
}
//When PersonName is null, it should throw ArgumentException
[Fact]
public async Task UpdatePerson_PersonNameIsNull()
{
//Arrange
CountryAddRequest countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "UK").Create();
CountryResponse countryResponse = await _countriesService.AddCountry(countryAddRequest);
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "John")
.With(p => p.Email, "John@example.com")
.With(p => p.CountryId, countryResponse.CountryId)
.Create();
PersonResponse personResponseAdd = await _personService.AddPerson(personAddRequest);
PersonUpdateRequest personUpdateRequest = personResponseAdd.ToPersonUpdateRequest();
personUpdateRequest.PersonName = null;
//Assert
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
//Act
await _personService.UpdatePerson(personUpdateRequest);
});
}
//Frist, add a new person and try to update the person name and email
[Fact]
public async Task UpdatePerson_PersonFullDetailsUpdation()
{
//Arrange
CountryAddRequest countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "UK").Create();
CountryResponse countryResponse = await _countriesService.AddCountry(countryAddRequest);
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "John")
.With(p => p.Email, "John@example.com")
.With(p => p.CountryId, countryResponse.CountryId)
.Create();
PersonResponse personResponseAdd = await _personService.AddPerson(personAddRequest);
PersonUpdateRequest personUpdateRequest = personResponseAdd.ToPersonUpdateRequest();
personUpdateRequest.PersonName = "William";
personUpdateRequest.Email = "William@example.com";
//Act
PersonResponse personResponseUpdate = await _personService.UpdatePerson(personUpdateRequest);
PersonResponse? personResponseGet = await _personService.GetPersonByPersonId(personUpdateRequest.PersonId);
//Assert
Assert.Equal(personResponseGet, personResponseUpdate);
}
#endregion
#region DeletePerson
//If you supply an valid PersonId, it should return true
[Fact]
public async Task DeletePerson_ValidPersonId()
{
//Arrange
CountryAddRequest countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "UK").Create();
CountryResponse countryResponse = await _countriesService.AddCountry(countryAddRequest);
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "John")
.With(p => p.Email, "John@example.com")
.With(p => p.CountryId, countryResponse.CountryId)
.Create();
PersonResponse personResponse = await _personService.AddPerson(personAddRequest);
//Act
bool isDeleted = await _personService.DeletePerson(personResponse.PersonId);
//Assert
Assert.True(isDeleted);
}
//If you supply an Invalid PersonId, it should return false
[Fact]
public async Task DeletePerson_InvalidPersonId()
{
//Arrange
CountryAddRequest countryAddRequest = _fixture.Build<CountryAddRequest>()
.With(c => c.CountryName, "UK").Create();
CountryResponse countryResponse = await _countriesService.AddCountry(countryAddRequest);
PersonAddRequest personAddRequest = _fixture.Build<PersonAddRequest>()
.With(p => p.PersonName, "John")
.With(p => p.Email, "John@example.com")
.With(p => p.CountryId, countryResponse.CountryId)
.Create();
PersonResponse personResponse = await _personService.AddPerson(personAddRequest);
//Act
bool isDeleted = await _personService.DeletePerson(Guid.NewGuid());
//Assert
Assert.False(isDeleted);
}
#endregion
}
}
Gitee获取源码: