Moq returns null 和 BadRequestObjectResult
Moq returns null and BadRequestObjectResult
我是单元测试的新手,正在尝试模拟 postContinent
。但是给出 null
和 BadRequestObjectResult
.
ContinentControllerTests
public class ContinentControllerTests {
// RepoMocks
private readonly Mock<IContinentRepository> _continentRepoMock = new Mock<IContinentRepository>();
private readonly Mock<ICountryRepository> _countryRepoMock = new Mock<ICountryRepository>();
private readonly Mock<ICityRepository> _cityRepoMock = new Mock<ICityRepository>();
// Controller
private readonly ContinentController _continentController;
public ContinentControllerTests() {
_continentServiceMock = new ContinentService(_continentRepoMock.Object);
_continentController = new ContinentController(new ContinentService(_continentRepoMock.Object), new CountryService(_countryRepoMock.Object), new CityService(_cityRepoMock.Object));
}
[Fact]
public void PostContinent_ValidInput_ReturnsCreateAtAction() {
// Arrange
_continentRepoMock
.Setup(repo => repo.HeeftContinent("Test"))
.Returns(false);
_continentRepoMock
.Setup(repo => repo.BestaatContinent(new Continent("Test", new List<Country>())))
.Returns(false);
_continentRepoMock
.Setup(repo => repo.VoegContinentToe(new Continent("Test", new List<Country>())))
.Returns(new Continent(1, "Test", new List<Country>()));
// Act
var response = _continentController.PostContinent(new ContinentInputDTO { Name = "Test" });
// Assert
Assert.IsType<CreatedAtActionResult>(response.Result);
}
}
大陆控制器
public class ContinentController : ControllerBase {
private string _hostURL = $"http://localhost:5000/api/continent";
private string _riverURL = $"http://localhost:5000/api/river";
private ContinentService _continentService;
private CountryService _countryService;
private CityService _cityService;
public ContinentController(ContinentService continentService, CountryService countryService, CityService cityService) {
_continentService = continentService;
_countryService = countryService;
_cityService = cityService;
}
[HttpPost]
public ActionResult<ContinentOutputDTO> PostContinent([FromBody] ContinentInputDTO continentDto) {
try {
if (_continentService.HeeftContinent(continentDto.Name)) { return BadRequest("Continent naam moet unique zijn!"); }
var mappedContinent = MapToDomain.MapToContinentDomain(continentDto);
Continent continent = _continentService.VoegContinentToe(mappedContinent);
return CreatedAtAction(nameof(GetContinent), new { continentId = continent.Id },
MapFromDomain.MapFromContinentDomain(_hostURL, continent));
}
catch (Exception ex) { return BadRequest(ex.Message); }
}
}
大陆服务
public class ContinentService {
private readonly IContinentRepository _repo;
public ContinentService(IContinentRepository repo) { _repo = repo;}
public Continent VoegContinentToe(Continent c) {
if (c == null) throw new ContinentServiceException("VoegContinentToe : continent is null");
if (_repo.BestaatContinent(c)) throw new ContinentServiceException("VoegContinentToe : continent bestaat reeds");
try {return _repo.VoegContinentToe(c);}
catch (Exception ex) { throw new ContinentServiceException("VoegContinentToe: ", ex);}
}
}
错误:
Message:
Assert.IsType() Failure
Expected: Microsoft.AspNetCore.Mvc.CreatedAtActionResult
Actual: Microsoft.AspNetCore.Mvc.BadRequestObjectResult
问题出在您的 Setup
函数中。仅当您覆盖了 equals 函数或者它们是完全相同的引用时,引用类型才相等。
所以通过new关键字设置,它永远不会匹配执行时间对象。
尝试使用 MOQ 中的 It.IsAny<T>
功能进行验证。
在此处查看示例:https://documentation.help/Moq/3CF54A74.htm
// Throws an exception for a call to Remove with any string value.
mock.Setup(x => x.Remove(It.IsAny<string>())).Throws(new InvalidOperationException());
例子。适用于所有设置。
_continentRepoMock
.Setup(repo => repo.BestaatContinent(It.IsAny<Continent>()))
.Returns(false);
我是单元测试的新手,正在尝试模拟 postContinent
。但是给出 null
和 BadRequestObjectResult
.
ContinentControllerTests
public class ContinentControllerTests {
// RepoMocks
private readonly Mock<IContinentRepository> _continentRepoMock = new Mock<IContinentRepository>();
private readonly Mock<ICountryRepository> _countryRepoMock = new Mock<ICountryRepository>();
private readonly Mock<ICityRepository> _cityRepoMock = new Mock<ICityRepository>();
// Controller
private readonly ContinentController _continentController;
public ContinentControllerTests() {
_continentServiceMock = new ContinentService(_continentRepoMock.Object);
_continentController = new ContinentController(new ContinentService(_continentRepoMock.Object), new CountryService(_countryRepoMock.Object), new CityService(_cityRepoMock.Object));
}
[Fact]
public void PostContinent_ValidInput_ReturnsCreateAtAction() {
// Arrange
_continentRepoMock
.Setup(repo => repo.HeeftContinent("Test"))
.Returns(false);
_continentRepoMock
.Setup(repo => repo.BestaatContinent(new Continent("Test", new List<Country>())))
.Returns(false);
_continentRepoMock
.Setup(repo => repo.VoegContinentToe(new Continent("Test", new List<Country>())))
.Returns(new Continent(1, "Test", new List<Country>()));
// Act
var response = _continentController.PostContinent(new ContinentInputDTO { Name = "Test" });
// Assert
Assert.IsType<CreatedAtActionResult>(response.Result);
}
}
大陆控制器
public class ContinentController : ControllerBase {
private string _hostURL = $"http://localhost:5000/api/continent";
private string _riverURL = $"http://localhost:5000/api/river";
private ContinentService _continentService;
private CountryService _countryService;
private CityService _cityService;
public ContinentController(ContinentService continentService, CountryService countryService, CityService cityService) {
_continentService = continentService;
_countryService = countryService;
_cityService = cityService;
}
[HttpPost]
public ActionResult<ContinentOutputDTO> PostContinent([FromBody] ContinentInputDTO continentDto) {
try {
if (_continentService.HeeftContinent(continentDto.Name)) { return BadRequest("Continent naam moet unique zijn!"); }
var mappedContinent = MapToDomain.MapToContinentDomain(continentDto);
Continent continent = _continentService.VoegContinentToe(mappedContinent);
return CreatedAtAction(nameof(GetContinent), new { continentId = continent.Id },
MapFromDomain.MapFromContinentDomain(_hostURL, continent));
}
catch (Exception ex) { return BadRequest(ex.Message); }
}
}
大陆服务
public class ContinentService {
private readonly IContinentRepository _repo;
public ContinentService(IContinentRepository repo) { _repo = repo;}
public Continent VoegContinentToe(Continent c) {
if (c == null) throw new ContinentServiceException("VoegContinentToe : continent is null");
if (_repo.BestaatContinent(c)) throw new ContinentServiceException("VoegContinentToe : continent bestaat reeds");
try {return _repo.VoegContinentToe(c);}
catch (Exception ex) { throw new ContinentServiceException("VoegContinentToe: ", ex);}
}
}
错误:
Message: Assert.IsType() Failure
Expected:Microsoft.AspNetCore.Mvc.CreatedAtActionResult
Actual:Microsoft.AspNetCore.Mvc.BadRequestObjectResult
问题出在您的 Setup
函数中。仅当您覆盖了 equals 函数或者它们是完全相同的引用时,引用类型才相等。
所以通过new关键字设置,它永远不会匹配执行时间对象。
尝试使用 MOQ 中的 It.IsAny<T>
功能进行验证。
在此处查看示例:https://documentation.help/Moq/3CF54A74.htm
// Throws an exception for a call to Remove with any string value.
mock.Setup(x => x.Remove(It.IsAny<string>())).Throws(new InvalidOperationException());
例子。适用于所有设置。
_continentRepoMock
.Setup(repo => repo.BestaatContinent(It.IsAny<Continent>()))
.Returns(false);