[英]How to mock DbContext using moq and nunit
Please i am trying to mock a DbContext and write a test, from my test the error seems to come from the mocking of the DbContext.请我试图模拟一个 DbContext 并编写一个测试,从我的测试来看,错误似乎来自 DbContext 的 mocking。 maybe the way i set it up isn't correct.
也许我设置的方式不正确。 can anyone spot the error or a better way of setting it up?
任何人都可以发现错误或更好的设置方法吗? Thanks
谢谢
Test and Setup: upVoteControllerTest.cs测试和设置:upVoteControllerTest.cs
[SetUp]
public void Setup()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MapperInitilizer>();
});
_realMapper = new Mapper(config);
_upvotes = new Mock<IRepository<Upvote>>();
_unitOfWork = new Mock<IUnitOfWork>();
_unitOfWork.SetupGet(work => work.Upvotes).Returns(_upvotes.Object);
_logger = new Mock<ILogger<UpvoteController>>();
_mapper = new Mock<IMapper>();
_context = new Mock<ApplicationDbContext>();
_upvoteController = new UpvoteController(_context.Object, _mapper.Object,_unitOfWork.Object, _logger.Object);
upvote_one = new Upvote()
{
Id = 1,
UserId = "43434343434",
TopicId = 1
};
upvote_two = new Upvote()
{
Id = 2,
UserId = "65664535",
TopicId = 2
};
user_one = new User()
{
Id = "43434343434",
FirstName = "john",
LastName = "doe",
Email = "john@gmail.com",
Photo = "hgghghg",
PhoneNumber = "fgfffgfg"
};
List<User> expectedResult = new List<User> {user_one};
var repo = new UserTestRepository();
}
[Test]
public void GetAllUpVotes_SendRequest_ReturnListOfUpVotes()
{
List<Upvote> expectedResult = new List<Upvote> {upvote_one, upvote_two};
var repo = new UpvoteTestRepository(expectedResult);
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(work => work.Upvotes).Returns(repo);
_upvoteController.GetUpvotes().GetAwaiter().GetResult();
Assert.IsNotEmpty(repo.Source);
CollectionAssert.AreEqual(expectedResult, repo.GetAll().GetAwaiter().GetResult());
}
UpvoteController:投票控制器:
public UpvoteController(ApplicationDbContext context, IMapper mapper,
IUnitOfWork unitOfWork, ILogger<UpvoteController> logger)
{
_context = context;
_mapper = mapper;
_unitOfWork = unitOfWork;
_logger = logger;
}
// GET: api/Upvote
[HttpGet]
public async Task<IActionResult> GetUpvotes()
{
try
{
var upvotes = await _unitOfWork.Upvotes.GetAll();
var results = _mapper.Map<IList<UpvoteDTO>>(upvotes);
return Ok(results);
}
catch (Exception e)
{
_logger.LogError(e, $"Something went wrong in the {nameof(GetUpvotes)}");
return StatusCode(500, "Internal server error");
}
}
UpvoteTestRepository: UpvoteTestRepository:
public class UpvoteTestRepository : IRepository<Upvote>
{
public IList<Upvote> Source;
public UpvoteTestRepository(IList<Upvote> source)
{
Source = source;
}
public Task<Upvote> Get(Expression<Func<Upvote, bool>> expression,
Func<IQueryable<Upvote>, IIncludableQueryable<Upvote, object>> include = null)
{
IQueryable<Upvote> query = Source.AsQueryable();
return Task.FromResult(query.FirstOrDefault(expression));
}
public Task<IList<Upvote>> GetAll(Expression<Func<Upvote, bool>> expression = null, Func<IQueryable<Upvote>, IOrderedQueryable<Upvote>> orderBy = null, Func<IQueryable<Upvote>, IIncludableQueryable<Upvote, object>> include = null, Expression<Func<Upvote, bool>> cat = null,
int limit = 0)
{
return Task.FromResult(Source);
}
}
Error:错误:
System.ArgumentException : Can not instantiate proxy of class: dotnetapp.Data.ApplicationDbContext.
Could not find a parameterless constructor. (Parameter 'constructorArguments')
----> System.MissingMethodException : Constructor on type 'Castle.Proxies.ApplicationDbContextProxy' not found.
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[]
You can use in-memory db.您可以使用内存数据库。 But that's not such a good decision, there you can see why, but in general, if your app(db in general) is small it`s okay.
但这不是一个很好的决定,在那里你可以明白为什么,但总的来说,如果你的应用程序(一般的数据库)很小,那没关系。
var options = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new MyDbContext(options);
context.Database.EnsureCreated();
In addition you can do it much better with EF Effort .此外,您可以使用EF Effort做得更好。 Which also use in-memory db, but efficient way
这也使用内存数据库,但有效的方式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.