C# xUnit测试和.NET Core 2.0中的Automapper
我有一个.NETCore2.0项目,其中包含存储库模式和xUnit测试 现在,这里是它的一些代码 控制器: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
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,我修复了这个问题,它工作正常,我发布了我的答案,但还有一个棘手的问题,我正试图从早上开始解决,我想我需要你的帮助。