Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 使用NUnit和NSubstitute的单元测试中间件_Unit Testing_Asp.net Core_Nunit_Middleware_Nsubstitute - Fatal编程技术网

Unit testing 使用NUnit和NSubstitute的单元测试中间件

Unit testing 使用NUnit和NSubstitute的单元测试中间件,unit-testing,asp.net-core,nunit,middleware,nsubstitute,Unit Testing,Asp.net Core,Nunit,Middleware,Nsubstitute,我已经在ASP.NET核心站点中编写了一些中间件,我正在尝试对其进行单元测试,主要是通过以下方法来实现 我的问题是为新的DefaultHttpContext()找到NUnit/NSubstitute等效项。替换HttpContext将触发中间件,但它会传递try。我想这是因为下面引用的问题。NUnit是否具有创建真实HttpContext的功能,或者我是否正在寻找更多的基础设施来实现这一点 我正在向Invoke方法发送DefaultHttpContext的实例。我不能在这个场景中使用模拟的Htt

我已经在ASP.NET核心站点中编写了一些中间件,我正在尝试对其进行单元测试,主要是通过以下方法来实现

我的问题是为
新的DefaultHttpContext()
找到NUnit/NSubstitute等效项。替换HttpContext将触发中间件,但它会传递
try
。我想这是因为下面引用的问题。NUnit是否具有创建真实HttpContext的功能,或者我是否正在寻找更多的基础设施来实现这一点

我正在向Invoke方法发送DefaultHttpContext的实例。我不能在这个场景中使用模拟的HttpContext,因为第一个中间件(我们传递给构造函数的lambda函数)需要写入响应。因此,HttpResponse需要是一个真实的对象,而不是模拟的对象

这是我的测试代码

[TestFixture]
public class ExceptionHelperTests
{
    private IErrorRepository errorRepository;
    private ExceptionHandler handler;

    [SetUp]
    public void Setup()
    {
        errorRepository = Substitute.For<IErrorRepository>();
    }

    [Test]
    public async void Given_AnExceptionHappens_Then_ItShouldBeLogged()
    {
        // Arrange
        const string username = "aUser";
        var user = Substitute.For<ClaimsPrincipal>();
        user.Identity.Name.Returns(username);

        handler = new ExceptionHandler(
            next: async (innerHttpContext) =>
            {
                innerHttpContext.User = user;
            },
            repository: errorRepository);

        // Act
        await handler.Invoke(new DefaultHttpContext());

        // Assert
        errorRepository.Received().LogException(Arg.Any<string>(), Arg.Any<Exception>(), Arg.Is(username));
    }
}
以下是中间件(带有简化的HandleException):


DefaultHttpContext
只是抽象类的默认实现

你能做到的

var HttpContextSub = Substitute.For<HttpContext>();
var HttpContextSub=Substitute.For();

DefaultHttpContext
是.net核心的一部分,而不是测试框架。有什么问题?当前的解释不清楚。请避免
async void
。进行测试
async任务
如果执行tap,您还可以显示测试中的方法,以使问题成为a。我已经添加了中间件代码。我原本认为这是一个严格的设计,没有什么帮助,但也许我错了。这样的替换允许设置和传递标识,但不会抛出异常
public sealed class ExceptionHandler
{
    private readonly RequestDelegate _next;
    private readonly IErrorRepository repository;

    public ExceptionHandler(RequestDelegate next, IErrorRepository repository)
    {
        _next = next;
        this.repository = repository;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            HandleException(ex, context.User.Identity.Name);
        }
    }

    public void HandleException(Exception ex, string userId)
    {
        repository.LogException("An unhandled exception has occurred.", ex, userId);
    }
}
var HttpContextSub = Substitute.For<HttpContext>();