在asp.net Web API核心应用程序中使用xunit测试Crud操作

问题描述 投票:0回答:1

我对单元测试完全陌生,希望为我的控制器编写单元测试下面使用xunit和moq。我了解您只能模拟数据库事务,并且使单元测试独立于数据库。我该如何为这些编写xunit测试?任何文档或示例代码将不胜感激。我知道如何将xnit测试项目添加到我的解决方案中。

    using System;
    using System.Threading.Tasks;
    using CoreServices.Models;
    using CoreServices.Repository;
    using Microsoft.AspNetCore.Mvc;

    namespace CoreServices.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class PostController : ControllerBase
        {
            IPostRepository postRepository;
            public PostController(IPostRepository _postRepository)
            {
                postRepository = _postRepository;
            }

            [HttpGet]
            [Route("GetCategories")]
            public async Task<IActionResult> GetCategories()
            {
                try
                {
                    var categories = await postRepository.GetCategories();
                    if (categories == null)
                    {
                        return NotFound();
                    }

                    return Ok(categories);
                }
                catch (Exception)
                {
                    return BadRequest();
                }

            }

            [HttpGet]
            [Route("GetPosts")]
            public async Task<IActionResult> GetPosts()
            {
                try
                {
                    var posts = await postRepository.GetPosts();
                    if (posts == null)
                    {
                        return NotFound();
                    }

                    return Ok(posts);
                }
                catch (Exception)
                {
                    return BadRequest();
                }
            }

            [HttpGet]
            [Route("GetPost")]
            public async Task<IActionResult> GetPost(int? postId)
            {
                if (postId == null)
                {
                    return BadRequest();
                }

                try
                {
                    var post = await postRepository.GetPost(postId);

                    if (post == null)
                    {
                        return NotFound();
                    }

                    return Ok(post);
                }
                catch (Exception)
                {
                    return BadRequest();
                }
            }

            [HttpPost]
            [Route("AddPost")]
            public async Task<IActionResult> AddPost([FromBody]Post model)
            {
                if (ModelState.IsValid)
                {
                    try
                    {
                        var postId = await postRepository.AddPost(model);
                        if (postId > 0)
                        {
                            return Ok(postId);
                        }
                        else
                        {
                            return NotFound();
                        }
                    }
                    catch (Exception)
                    {

                        return BadRequest();
                    }

                }

                return BadRequest();
            }

            [HttpPost]
            [Route("DeletePost")]
            public async Task<IActionResult> DeletePost(int? postId)
            {
                int result = 0;

                if (postId == null)
                {
                    return BadRequest();
                }

                try
                {
                    result = await postRepository.DeletePost(postId);
                    if (result == 0)
                    {
                        return NotFound();
                    }
                    return Ok();
                }
                catch (Exception)
                {

                    return BadRequest();
                }
            }


            [HttpPost]
            [Route("UpdatePost")]
            public async Task<IActionResult> UpdatePost([FromBody]Post model)
            {
                if (ModelState.IsValid)
                {
                    try
                    {
                        await postRepository.UpdatePost(model);

                        return Ok();
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType().FullName == "Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException")
                        {
                            return NotFound();
                        }

                        return BadRequest();
                    }
                }

                return BadRequest();
            }

        }
    }
c# asp.net-core-webapi xunit.net
1个回答
1
投票

您可以使用新的PostController(postRepository)实例化该控制器。如果您需要一个用于后存储库的模拟,则可以使用一个名为Moq的库。 (使用nuget获取它)。只需写:

using Moq;

Mock<IPostRepository> postRepositoryMock = new Mock<IPostRepository>();
PostController controller = new PostController(postRepositoryMock.Object);

然后,您可以在Mock上使用Setup方法来返回所需的内容。例如,以某种方式返回给定类型int?的给定ID的测试Post来模拟Get方法:

postRepositoryMock.Setup(it => it.Get(It.IsAny<int?>()).Returns(new Post() { //here what you need to build your post object })

然后,您可以执行代码以从控制器获得结果,例如(测试代码是使用NUnit编写的,我不使用xunit,但是概念相同):

using Moq;

[TestFixture]
public class ExampleFixture()
{
    [Test]
    public void ExampleTest()
    { 

        Mock<IPostRepository> postRepositoryMock = new Mock<IPostRepository>();

        PostController controller = new PostController(postRepositoryMock.Object);

        postRepositoryMock.Setup(it => it.Get(It.IsAny<int?>()).Returns(new Post() { //here what you need to build your post object })

        var result = controller.GetPost(1);

        Assert.That(result, Is.Not.Null, "Unexpected null result");

        var retrievedPostContent = result as OkNegotiatedContentResult<Post>;
        Assert.That(retrievedPostContent, Is.Not.Null, "Unexpected null retrievedPost");
        var retrievedPost = result.Content;
        Assert.That(retrievedPost.Id, Is.EqualTo(1), "retrievedPost.Id is unexpected")
    }
}

使用xUnit应该成为:

using Xunit;
using Moq;

namespace ATestNamespace
{
public class TestFixture
{

    public TestFixture()
    {

    }

    [Fact]
    public void Test()
    {

        Mock<IPostRepository> postRepositoryMock = new Mock<IPostRepository>();

        PostController controller = new PostController(postRepositoryMock.Object);

        postRepositoryMock.Setup(it => it.Get(It.IsAny<int?>()).Returns(new Post() { //here what you need to build your post object });

        var result = controller.GetPost(1);
        Assert.True(result != null,"Unexpected null result");

        var retrievedPostResult = result as OkNegotiatedContentResult<Post>;
        Assert.True(retrievedPostResult != null, "Unexpected null retrievedPost");

        var retrievedPost = result.Content;
        Assert.True(retrievedPost.Id == 1, "retrievedPost.Id is unexpected")
    }
}
}
© www.soinside.com 2019 - 2024. All rights reserved.