NUnit使用ModelViewFactory和存储库Mock

时间:2017-04-16 16:06:45

标签: c# unit-testing nunit moq

我在使用ModelViewFactory和存储库模拟创建NUnit测试时遇到了一些麻烦。

我的测试应测试我的控制器Get-function是否返回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,当这个工作时我会使用更多。 我得到的错误是Error message

有人可以帮帮我吗?非常感谢帮助,因为我不知道我做错了什么。

2 个答案:

答案 0 :(得分:1)

看起来你不能模仿InternshipsViewModelFactory,因为它是一个具体的非抽象类型。您应该创建(并使用)接口IInternshipsViewModelFactory

然后Mock将能够创建自己的IInternshipsViewModelFactory实现,它将按照您在模拟的Setup方法中描述的方式运行。

答案 1 :(得分:1)

首先,测试方法是直接新建工厂。用于测试的模拟无法替换的方法。

考虑抽象工厂和界面,以便在测试中替换它时提供更大的灵活性。

public interface IInternshipsViewModelFactory {
    IEnumerable<InternshipsWithFeedbackViewModel> CreateInternshipsViewModel(IInternshipRepository internshipRepository, IEnumerable<Internship> internships);
}

确保实现继承自上面的接口/抽象。

通过将相关性注入控制器来反转控制器中的控件。

例如

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);

}