Skip to content

CancelAfter & TestCaseSource with CancellationToken method parameter cause test failures #4900

@doxxx

Description

@doxxx

NUnit 4.3.0
NUnit.Analyzers 4.4.0
NUnit3TestAdapter 4.6.0

I have a test defined like so:

[Test, TestCaseSource(nameof(ValidSyslogMessages)), CancelAfter(5000)]
public void TestLogSendAndReceive_Success(string syslogMessage, LogLevel logLevel, string message, CancellationToken cancellationToken)
{
    _logEvent.Reset();
    SendUdpMessage(syslogMessage, _port);
    cancellationToken.ThrowIfCancellationRequested();
    Assert.That(_logEvent.WaitOne(1000));
    Assert.That(_logReceived.Message, Is.EqualTo(message));
    Assert.That(_logReceived.LogLevel, Is.EqualTo(logLevel));
}

private static IEnumerable ValidSyslogMessages()
{
    yield return new object[] { "<160>1 2003-08-24T05:14:15.000003-07:00 %% Severity 0 : emerg", LogLevel.Fatal, "%% Severity 0 : emerg" };
    // ... more items
}

This compiles but fails at runtime with errors like so:

 TestLogSendAndReceive_Success(["<160>1 2003-08-24T05:14:15.000003-07:00 %% Severity 0 : emerg", Fatal, "%% Severity 0 : emerg"])
   Source: SysLogListenerTest.cs line 58
   Duration: < 1 ms

  Message: 
Not enough arguments provided, provide at least 4 arguments.

Similarly, another test method defined like so:

[Test, TestCaseSource(nameof(InvalidSyslogMessages)), CancelAfter(5000)]
public void TestLogSendAndReceive_Fail(string syslogMessage, CancellationToken cancellationToken)
{
    _logEvent.Reset();
    SendUdpMessage(syslogMessage, _port);
    cancellationToken.ThrowIfCancellationRequested();
    Assert.That(_logEvent.WaitOne(1000), Is.False);
}

private static IEnumerable InvalidSyslogMessages()
{
    yield return new object[] { "Test Not SysLog" };
}

This also compiles but fails at runtime with a different error:

 TestLogSendAndReceive_Fail(["Test Not SysLog XXX"])
   Source: SysLogListenerTest.cs line 69
   Duration: 118 ms

  Message: 
System.ArgumentException : Object of type 'System.Object[]' cannot be converted to type 'System.String'.

  Stack Trace: 
RuntimeType.CheckValue(Object& value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
MethodBase.Invoke(Object obj, Object[] parameters)
Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)

If I remove the CancellationToken parameter from these test methods and use TestExecutionContext.CurrentContext.CancellationToken instead, the tests work as expected.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions