簡體   English   中英

如何使用 moq 和 nunit 模擬 DbContext

[英]How to mock DbContext using moq and nunit

請我試圖模擬一個 DbContext 並編寫一個測試,從我的測試來看,錯誤似乎來自 DbContext 的 mocking。 也許我設置的方式不正確。 任何人都可以發現錯誤或更好的設置方法嗎? 謝謝

測試和設置: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());
    }

投票控制器:

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:

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

錯誤:

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[] 

您可以使用內存數據庫。 但這不是一個很好的決定,在那里你可以明白為什么,但總的來說,如果你的應用程序(一般的數據庫)很小,那沒關系。

var options = new DbContextOptionsBuilder<MyDbContext>()
                      .UseInMemoryDatabase(Guid.NewGuid().ToString())
                      .Options;
var context = new MyDbContext(options);
context.Database.EnsureCreated();

此外,您可以使用EF Effort做得更好。 這也使用內存數據庫,但有效的方式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM