C# xUnit测试和.NET Core 2.0中的Automapper

C# xUnit测试和.NET Core 2.0中的Automapper,c#,unit-testing,automapper,asp.net-core-2.0,xunit,C#,Unit Testing,Automapper,Asp.net Core 2.0,Xunit,我有一个.NETCore2.0项目,其中包含存储库模式和xUnit测试 现在,这里是它的一些代码 控制器: public class SchedulesController : Controller { private readonly IScheduleRepository repository; private readonly IMapper mapper; public SchedulesController(IScheduleRepository reposi

我有一个.NETCore2.0项目,其中包含存储库模式和xUnit测试

现在,这里是它的一些代码

控制器:

public class SchedulesController : Controller
{
    private readonly IScheduleRepository repository;
    private readonly IMapper mapper;

    public SchedulesController(IScheduleRepository repository, IMapper mapper)
    {
        this.repository = repository;
        this.mapper = mapper;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);
        return new OkObjectResult(result);
    }
}
public class SchedulesControllerTests
{
    [Fact]
    public void CanGet()
    {
        try
        {
            //Arrange
            Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
            mockRepo.Setup(m => m.items).Returns(new Schedule[]
            {
                new Schedule() { Id=1, Title = "Schedule1" },
                new Schedule() { Id=2, Title = "Schedule2" },
                new Schedule() { Id=3, Title = "Schedule3" }
            });

            var mockMapper = new Mock<IMapper>();
            mockMapper.Setup(x => x.Map<Schedule>(It.IsAny<ScheduleDto>()))
                .Returns((ScheduleDto source) => new Schedule() { Title = source.Title });

            SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mockMapper.Object);

            //Act
            var result = controller.Get();

            //Assert
            var okResult = result as OkObjectResult;
            Assert.NotNull(okResult);

            var model = okResult.Value as IEnumerable<ScheduleDto>;
            Assert.NotNull(model);

        }
        catch (Exception ex)
        {
            //Assert
            Assert.False(false, ex.Message);
        }
    }
}
公共类调度控制器:控制器
{
私有只读存储库;
专用只读IMapper映射器;
公共调度控制器(ISScheduleRepository存储库,IMapper映射器)
{
this.repository=存储库;
this.mapper=mapper;
}
[HttpGet]
public IActionResult Get()
{
var result=mapper.Map(来源:repository.items);
返回新的OkObjectResult(结果);
}
}
我的测试类:

public class SchedulesController : Controller
{
    private readonly IScheduleRepository repository;
    private readonly IMapper mapper;

    public SchedulesController(IScheduleRepository repository, IMapper mapper)
    {
        this.repository = repository;
        this.mapper = mapper;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);
        return new OkObjectResult(result);
    }
}
public class SchedulesControllerTests
{
    [Fact]
    public void CanGet()
    {
        try
        {
            //Arrange
            Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
            mockRepo.Setup(m => m.items).Returns(new Schedule[]
            {
                new Schedule() { Id=1, Title = "Schedule1" },
                new Schedule() { Id=2, Title = "Schedule2" },
                new Schedule() { Id=3, Title = "Schedule3" }
            });

            var mockMapper = new Mock<IMapper>();
            mockMapper.Setup(x => x.Map<Schedule>(It.IsAny<ScheduleDto>()))
                .Returns((ScheduleDto source) => new Schedule() { Title = source.Title });

            SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mockMapper.Object);

            //Act
            var result = controller.Get();

            //Assert
            var okResult = result as OkObjectResult;
            Assert.NotNull(okResult);

            var model = okResult.Value as IEnumerable<ScheduleDto>;
            Assert.NotNull(model);

        }
        catch (Exception ex)
        {
            //Assert
            Assert.False(false, ex.Message);
        }
    }
}
公共类SchedulesControllerTests
{
[事实]
公共无效目录()
{
尝试
{
//安排
Mock mockRepo=新Mock();
mockRepo.Setup(m=>m.items).Returns(新计划[]
{
新计划(){Id=1,Title=“Schedule1”},
新计划(){Id=2,Title=“Schedule2”},
新计划(){Id=3,Title=“Schedule3”}
});
var mockMapper=new Mock();
mockMapper.Setup(x=>x.Map(It.IsAny())
.Returns((ScheduleDto source)=>newschedule(){Title=source.Title});
SchedulesController=new SchedulesController(存储库:mockRepo.Object,映射器:mockMapper.Object);
//表演
var result=controller.Get();
//断言
var okResult=结果为OkObjectResult;
Assert.NotNull(okResult);
var模型=okResult.Value作为IEnumerable;
Assert.NotNull(模型);
}
捕获(例外情况除外)
{
//断言
Assert.False(False,例如Message);
}
}
}
我面临的问题。

我的问题是,当我在数据库上下文中运行这段代码并执行
Get()
方法时,它工作正常,会给出所有结果

但当我尝试运行测试用例时,它不会返回Dto对象的任何数据。 当我调试时,我发现

  • 我正在使用
    mockRepo
    在控制器中获取测试对象

  • 但看起来自动映射器没有正确初始化,因为在映射过程中,它没有返回任何内容

    var result=mapper.Map(来源:repository.items)

  • 到目前为止我尝试了什么?

    我遵循了所有这些答案,但仍然不起作用


    因此,我需要一位精通xUnit和automapper的人的帮助,并需要关于如何正确初始化模拟映射程序的指导。

    最终它对我有效,我遵循了这一方法

    在这里我张贴我的答案和测试类,所以如果需要其他so可以使用

    public class SchedulesControllerTests
    {
        [Fact]
        public void CanGet()
        {
            try
            {
                //Arrange
                //Repository
                Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
                var schedules = new List<Schedule>(){
                    new Schedule() { Id=1, Title = "Schedule1" },
                    new Schedule() { Id=2, Title = "Schedule2" },
                    new Schedule() { Id=3, Title = "Schedule3" }
                };
    
                mockRepo.Setup(m => m.items).Returns(value: schedules);
    
                //auto mapper configuration
                var mockMapper = new MapperConfiguration(cfg =>
                {
                    cfg.AddProfile(new AutoMapperProfile());
                });
                var mapper = mockMapper.CreateMapper();
    
                SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mapper);
    
                //Act
                var result = controller.Get();
    
                //Assert
                var okResult = result as OkObjectResult;
                if (okResult != null)
                    Assert.NotNull(okResult);
    
                var model = okResult.Value as IEnumerable<ScheduleDto>;
                if (model.Count() > 0)
                {
                    Assert.NotNull(model);
    
                    var expected = model?.FirstOrDefault().Title;
                    var actual = schedules?.FirstOrDefault().Title;
    
                    Assert.Equal(expected: expected, actual: actual);
                }
            }
            catch (Exception ex)
            {
                //Assert
                Assert.False(false, ex.Message);
            }
        }
    }
    
    公共类SchedulesControllerTests
    {
    [事实]
    公共无效目录()
    {
    尝试
    {
    //安排
    //存储库
    Mock mockRepo=新Mock();
    var schedules=新列表(){
    新计划(){Id=1,Title=“Schedule1”},
    新计划(){Id=2,Title=“Schedule2”},
    新计划(){Id=3,Title=“Schedule3”}
    };
    mockRepo.Setup(m=>m.items).Returns(值:schedules);
    //自动映射器配置
    var mockMapper=新的映射配置(cfg=>
    {
    AddProfile(新的AutoMapperProfile());
    });
    var mapper=mockMapper.CreateMapper();
    SchedulesController controller=新的SchedulesController(存储库:mockRepo.Object,映射器:映射器);
    //表演
    var result=controller.Get();
    //断言
    var okResult=结果为OkObjectResult;
    if(okResult!=null)
    Assert.NotNull(okResult);
    var模型=okResult.Value作为IEnumerable;
    如果(model.Count()>0)
    {
    Assert.NotNull(模型);
    var expected=model?.FirstOrDefault().Title;
    var实际值=计划?.FirstOrDefault().Title;
    Assert.Equal(预期:预期,实际:实际);
    }
    }
    捕获(例外情况除外)
    {
    //断言
    Assert.False(False,例如Message);
    }
    }
    }
    
    我需要注入
    IMapper
    ,使用
    ProjectTo
    获取映射的
    IQueryable
    ,然后在映射后的queryable上实现更多的逻辑。所以我是这样嘲笑它的:

    var models = new object[]
    {
        ⋮
    }.AsQueryable();
    var mapper = new Mock<IMapper>();
    mapper.Setup(x => x.ProjectTo(
            It.IsAny<IQueryable>(),
            It.IsAny<object>(),
            It.IsAny<Expression<Func<object, object>>[]>()))
        .Returns(models);
    
    var模型=新对象[]
    {
    ⋮
    }.AsQueryable();
    var mapper=newmock();
    mapper.Setup(x=>x.ProjectTo(
    It.IsAny(),
    It.IsAny(),
    It.IsAny())
    .退货(型号);
    
    您似乎在代码和moq设置中使用了不同的Map签名。不要模拟Map,试着模拟Map方法。@jcemoller最后它没有模拟就工作了,我只是创建了mapper对象,并将其与我的配置文件一起注入。@Bharat在你留下评论时正在写这篇文章作为答案。我不需要现在就做。您可以将其添加为问题的自我回答。这里是我在这里提供的一个类似的答案。请注意,它使用了不同的模拟框架,但automapper部分适用。谢谢@Nkosi,我修复了这个问题,它工作正常,我发布了我的答案,但还有一个棘手的问题,我正试图从早上开始解决,我想我需要你的帮助。