c# - 正确实现单元测试

标签 c# unit-testing signalr

我是第一次练习编写单元测试,我有一些问题。我将首先解释我要测试的内容。

我想测试一个如下所示的方法:

public bool IsAdmin(HubCallerContext hubCallerContext)
{
    return hubCallerContext.User.IsInRole("admin");
}

该方法在类 UserService 中实现,该类连接到接口(interface) IUserService

我正在尝试创建 2 个测试:

  • 具有 HubCallerContext,其角色为“管理员”,并将断言 true。
  • 具有 HubCallerContext 的角色,该上下文充当“用户”角色,并将断言为 false。

我在解决方案中创建了一个新的类库,其中引用了我正在测试的项目。我已经安装了 NUnit 和 Moq,并创建了一个测试类,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChatProj;
using NUnit.Framework;
using ChatProj.Controllers;
using Moq;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using ChatProj.DAL;
using ChatProj.Service_Layer;
using System.Threading.Tasks;

namespace ChatProj.Tests
{
    [TestFixture]
    public class Class1
    {

        [SetUp]
        public void Setup()
        {

        }

        [Test]
    public void IsAdmin_CalledByAdmin_ReturnTrue()
    {
        UserService userService = new UserService();
        bool result = userService.IsAdmin( ? );
        Assert.IsTrue( result, "Something is wrong." );
    }

    [Test]
    public void IsAdmin_CalledByUser_ReturnFalse()
    {
        UserService userService = new UserService();
        bool result = userService.IsAdmin( ? );
        Assert.IsFalse( result, "Something is wrong." );
    }

    }
}

这里我开始感到困惑。 (我用“?”标记了 IsAdmin 调用的参数,因为我不确定要放在那里。)

我读过有关模拟、 stub 、假货和假人的内容,但这些定义对于我来说太抽象了,无法真正理解。例如,我找到了这些定义:

 - Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.

 - Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).

 - Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.

 - Mocks are objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

当我设计我的测试类时,我需要对我的 HubCallerContext 进行某种替换。这是假设我正在以正确的方式测试“IsAdmin”方法。

所以我的问题是:

  • 我是否以良好的方式测试“IsAdmin”方法?

  • 我该如何让测试真正发挥作用?我是否使用模拟,在这种情况下,您能否展示我将如何实现它,或者为我指出正确的方向? Here is how the HubCallerContext works for refrence.

最佳答案

假设 HubCallerContext 是这个 - https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Hubs/HubCallerContext.cs - 那么设置测试就会很容易。您只需要两个 IPrincipal 模拟,其中一个为 .IsInRole("admin") 调用返回 true,另一个返回 false。将这两个模拟IRequest

语法会根据所使用的模拟框架而有所不同,但您的测试最终将类似于:

[Test]
public void IsAdmin_CalledByAdmin_ReturnTrue()
{
    UserService userService = new UserService();
    var principalMock = new Mock<IPrincipal>();
    principalMock.Setup(x => x.IsInRole("admin")).Returns(true);
    var requestMock = new Mock<IRequest>();
    requestMock.Setup(x => x.User).Returns(principalMock.Object);
    var result = userService.IsAdmin(new HubCallerContext(requestMock.Object, ""));
    Assert.IsTrue( result, "Something is wrong." );
}

[Test]
public void IsAdmin_CalledByUser_ReturnFalse()
{
    UserService userService = new UserService();
    var principalMock = new Mock<IPrincipal>();
    principalMock.Setup(x => x.IsInRole("admin")).Returns(false);
    var requestMock = new Mock<IRequest>();
    requestMock.Setup(x => x.User).Returns(principalMock.Object);
    var result = userService.IsAdmin(new HubCallerContext(requestMock.Object, ""));
    Assert.IsFalse( result, "Something is wrong." );
}

我还没有检查上面的代码是否可以编译,但它是基于 Moq 所需的语法。 .

关于c# - 正确实现单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19908674/

相关文章:

c# - ApiController 的输出缓存(MVC4 Web API)

c# - public static float [ ] operator/( float [ ] a , int b ) 无法编译

c# - 我无法在 XAML 文件中写入阿拉伯文本

c# - 如何模拟执行复杂 Entity Framework LINQ 查询的对象?

python - 我可以在 Python unittest 中对测试方法和/或测试类进行分组吗

c# - DDD 上的免费视频(截屏视频、网络广播...)培训

java - 模拟内部最终对象

azure - 使用 SignalR Hub 交换 Azure 暂存/生产环境

javascript - ASP.NET Core 2.1 SignalR 未定义

asp.net - SignalR和浏览器连接限制