NUnit 使用 ModelViewFactory 和存储库 Mock 创建测试
NUnit create a test with a ModelViewFactory and a repository Mock
我在使用 ModelViewFactory
和存储库模拟创建 NUnit 测试时遇到了一些麻烦。
我的测试应该测试我的控制器 Get-function returns 是否是 InternshipsViewModel
s 的列表。
我的控制器:
public IHttpActionResult GetInternshipsForCoordinator()
{
return Ok(new InternshipsViewModelFactory().CreateInternshipsViewModel(_internshipRepository, _internshipRepository.GetAll()));
}
我的测试:
public void Get_ShouldReturnListOfInternshipsViewModel()
{
//Arrange
var allInternshipWithFeedbackViewModels = new List<InternshipsWithFeedbackViewModel>
{
new InternshipWithFeedbackViewModelBuilder().Build()
};
Mock<InternshipsViewModelFactory> internshipViewModelFactoryMock = new Mock<InternshipsViewModelFactory>();
internshipViewModelFactoryMock.Setup(
c =>
c.CreateInternshipsViewModel(It.IsAny<IInternshipRepository>(),
It.IsAny<IEnumerable<Internship>>())).Returns(() => allInternshipWithFeedbackViewModels);
//Act
var okResult =
_controller.GetInternshipsForCoordinator() as
OkNegotiatedContentResult<IEnumerable<InternshipsWithFeedbackViewModel>>;
//Assert
Assert.IsNotNull(okResult);
}
我知道我应该多用Asserts,这个能用的时候我会多用。
我得到的错误是
有人可以帮助我吗?非常感谢您的帮助,因为我不知道自己做错了什么。
看起来你不能模拟 InternshipsViewModelFactory
,因为它是一个具体的非抽象类型。您应该创建(并使用)接口 IInternshipsViewModelFactory
。
然后 Mock 将能够创建自己的 IInternshipsViewModelFactory
实现,它将按照您在 mock 的 Setup 方法中描述的方式运行。
首先测试的方法是直接new up factory。无法用mock代替测试的意思。
考虑抽象化背后的工厂和接口,以便在测试中替换它时具有更大的灵活性。
public interface IInternshipsViewModelFactory {
IEnumerable<InternshipsWithFeedbackViewModel> CreateInternshipsViewModel(IInternshipRepository internshipRepository, IEnumerable<Internship> internships);
}
确保实现继承自上述 interface/abstraction。
通过将该依赖项注入控制器来反转控制器中的控件。
例如
public class MyController : ApiController {
IInternshipsViewModelFactory factory;
IInternshipRepository _internshipRepository;
public MyController(IInternshipsViewModelFactory factory, IInternshipRepository repository) {
this.factory = factory;
this._internshipRepository = repository;
}
public IHttpActionResult GetInternshipsForCoordinator() {
var models = factory.CreateInternshipsViewModel(_internshipRepository, _internshipRepository.GetAll());
return Ok(models);
}
}
这将允许您模拟工厂,将其注入被测控制器并模拟测试所需的行为。
public void Get_ShouldReturnListOfInternshipsViewModel() {
//Arrange
var allInternshipWithFeedbackViewModels = new List<InternshipsWithFeedbackViewModel> {
//...populate collection
};
var internshipViewModelFactoryMock = new Mock<IInternshipsViewModelFactory>();
internshipViewModelFactoryMock
.Setup(_ => _.CreateInternshipsViewModel(It.IsAny<IInternshipRepository>(), It.IsAny<IEnumerable<Internship>>()))
.Returns(() => allInternshipWithFeedbackViewModels);
var repositoryMock = new Mock<IInternshipRepository>();
repositoryMock.Setup(_ => _.GetAll()).Returns(new List<Internship>());
var _controller = new MyController(internshipViewModelFactoryMock.Object, repositoryMock.Object);
//Act
var okResult =
_controller.GetInternshipsForCoordinator() as
OkNegotiatedContentResult<IEnumerable<InternshipsWithFeedbackViewModel>>;
//Assert
Assert.IsNotNull(okResult);
}
我在使用 ModelViewFactory
和存储库模拟创建 NUnit 测试时遇到了一些麻烦。
我的测试应该测试我的控制器 Get-function returns 是否是 InternshipsViewModel
s 的列表。
我的控制器:
public IHttpActionResult GetInternshipsForCoordinator()
{
return Ok(new InternshipsViewModelFactory().CreateInternshipsViewModel(_internshipRepository, _internshipRepository.GetAll()));
}
我的测试:
public void Get_ShouldReturnListOfInternshipsViewModel()
{
//Arrange
var allInternshipWithFeedbackViewModels = new List<InternshipsWithFeedbackViewModel>
{
new InternshipWithFeedbackViewModelBuilder().Build()
};
Mock<InternshipsViewModelFactory> internshipViewModelFactoryMock = new Mock<InternshipsViewModelFactory>();
internshipViewModelFactoryMock.Setup(
c =>
c.CreateInternshipsViewModel(It.IsAny<IInternshipRepository>(),
It.IsAny<IEnumerable<Internship>>())).Returns(() => allInternshipWithFeedbackViewModels);
//Act
var okResult =
_controller.GetInternshipsForCoordinator() as
OkNegotiatedContentResult<IEnumerable<InternshipsWithFeedbackViewModel>>;
//Assert
Assert.IsNotNull(okResult);
}
我知道我应该多用Asserts,这个能用的时候我会多用。
我得到的错误是
有人可以帮助我吗?非常感谢您的帮助,因为我不知道自己做错了什么。
看起来你不能模拟 InternshipsViewModelFactory
,因为它是一个具体的非抽象类型。您应该创建(并使用)接口 IInternshipsViewModelFactory
。
然后 Mock 将能够创建自己的 IInternshipsViewModelFactory
实现,它将按照您在 mock 的 Setup 方法中描述的方式运行。
首先测试的方法是直接new up factory。无法用mock代替测试的意思。
考虑抽象化背后的工厂和接口,以便在测试中替换它时具有更大的灵活性。
public interface IInternshipsViewModelFactory {
IEnumerable<InternshipsWithFeedbackViewModel> CreateInternshipsViewModel(IInternshipRepository internshipRepository, IEnumerable<Internship> internships);
}
确保实现继承自上述 interface/abstraction。
通过将该依赖项注入控制器来反转控制器中的控件。
例如
public class MyController : ApiController {
IInternshipsViewModelFactory factory;
IInternshipRepository _internshipRepository;
public MyController(IInternshipsViewModelFactory factory, IInternshipRepository repository) {
this.factory = factory;
this._internshipRepository = repository;
}
public IHttpActionResult GetInternshipsForCoordinator() {
var models = factory.CreateInternshipsViewModel(_internshipRepository, _internshipRepository.GetAll());
return Ok(models);
}
}
这将允许您模拟工厂,将其注入被测控制器并模拟测试所需的行为。
public void Get_ShouldReturnListOfInternshipsViewModel() {
//Arrange
var allInternshipWithFeedbackViewModels = new List<InternshipsWithFeedbackViewModel> {
//...populate collection
};
var internshipViewModelFactoryMock = new Mock<IInternshipsViewModelFactory>();
internshipViewModelFactoryMock
.Setup(_ => _.CreateInternshipsViewModel(It.IsAny<IInternshipRepository>(), It.IsAny<IEnumerable<Internship>>()))
.Returns(() => allInternshipWithFeedbackViewModels);
var repositoryMock = new Mock<IInternshipRepository>();
repositoryMock.Setup(_ => _.GetAll()).Returns(new List<Internship>());
var _controller = new MyController(internshipViewModelFactoryMock.Object, repositoryMock.Object);
//Act
var okResult =
_controller.GetInternshipsForCoordinator() as
OkNegotiatedContentResult<IEnumerable<InternshipsWithFeedbackViewModel>>;
//Assert
Assert.IsNotNull(okResult);
}