【问题标题】:Match a func delegate in argument matcher in nsubstitute Received method在 nsubstitute Received 方法中匹配参数匹配器中的 func 委托
【发布时间】:2019-12-02 09:37:14
【问题描述】:

我正在尝试检查一个方法是否在类的模拟实例上被调用了特定次数。问题是该方法有一个 func delegate 并且不匹配。

我有以下场景:

public interface ISomeService: IService
{
    Task CleanupMethod(CancellationToken cancellationToken);
}

public interface I
{
    Task invokedMethod(string aName, Func<IService, Task> action);
}


public class ClassGoingToBeUnitTested
{
    // instance of I
    private I instanceOfI;

    // a list of names.
    private static readonly string[] serviceNames =
    {
        "Name1",
        "Name2"
    };

    // constructor
    public ClassGoingToBeUnitTested(I passedInstance)
    {
        this.instanceOfI = passedInstance;
    }


    public void methodToBeUnitTested(object cancellationToken)
    {
        // my logic here

        // here I am calling invokedMethod method to known number of times.
        // something like this.

        try
        {
            IEnumerable<Task> someTasks = serviceNames.Select(
                name => this.instanceOfI.invokedMethod(
                    name,
                    service => ((ISomeService)service).CleanupMethod((CancellationToken)cancellationToken)
                    ));

            // here I run the tasks
            Task.WaitAll(someTasks.ToArray());

        }
        catch
        {
            // proper catching of exceptions
        }

        // other logic
    }
}


[TestClass]
public class ClassGoingToBeUnitTestedTest
{
    // mock of I interface
    private I IMock;

    // ClassGoingToBeUnitTested object
    ClassGoingToBeUnitTested classGoingToBeUnitTested;

    [TestInitialize]
    public void init()
    {
        this.IMock = Substitute.For<I>();
        this.classGoingToBeUnitTested = new ClassGoingToBeUnitTested(this.IMock);
    }


    [TestMethod]
    public void methodToBeUnitTested_Success()
    {
        // Arrange
        var cancellationTokenSource = new CancellationTokenSource();

        // Act
        this.classGoingToBeUnitTested.methodToBeUnitTested(cancellationTokenSource.Token);

        // Assert
        // this is throwing exception.
        this.IMock.Received(1).invokedMethod(
             "Name1",
             service => ((ISomeService)service).CleanupMethod((CancellationToken)cancellationTokenSource.Token)); // problem lies in this line.

    }
}

在上面的代码中,如果我将((ISomeService)service).CleanupMethod((CancellationToken)cancellationTokenSource.Token)) 更改为Arg.Any&lt;Func&lt;IService, Task&gt;(),它会完美运行。但我不想检查我的用例。

到目前为止,我已经能够调试参数匹配器通过引用匹配委托,因此无法正确匹配参数。但我无法正确匹配参数。

我也尝试调用委托,但没有成功。我想我错过了一些东西。任何帮助将不胜感激。

【问题讨论】:

    标签: c# unit-testing nsubstitute argument-matching


    【解决方案1】:

    我通过使用Invoke 解决了这个问题。我首先模拟了invokedMethod 的行为,以便在调用模拟的serviceInstanceMock 时调用它,然后检查CleanupMethodserviceInstanceMock 本身上被调用的次数。

    [TestClass]
    public class ClassGoingToBeUnitTestedTest
    {
        // mock of I interface
        private I IMock;
    
        // mock of ISomeService
        private ISomeService someServiceMockInstance;
    
        // ClassGoingToBeUnitTested object
        ClassGoingToBeUnitTested classGoingToBeUnitTested;
    
        [TestInitialize]
        public void init()
        {
            this.IMock = Substitute.For<I>();
            this.ISomeService = Substitute.For<ISomeService>();
            this.classGoingToBeUnitTested = new ClassGoingToBeUnitTested(this.IMock);
        }
    
    
        [TestMethod]
        public void methodToBeUnitTested_Success()
        {
            // Arrange
            var cancellationTokenSource = new CancellationTokenSource();
            this.IMock.invokedMethod(
                Arg.Any<string>,
                Arg.Do<Func<IService, Task>(x => x.Invoke(this.someServiceMockInstance)));
    
            // Act
            this.classGoingToBeUnitTested.methodToBeUnitTested(cancellationTokenSource.Token);
    
            // Assert
            this.IMock.Received(1).invokedMethod(
                 "Name1",
                 Arg.Any<Func<IService, Task>()); // changed this
    
            this.IMock.Received(1).invokedMethod(
                 "Name2",
                 Arg.Any<Func<IService, Task>()); // added this as well
    
            // adding to check the Received call on the service instance
            this.someServiceMockInstance.Received(2).CleanupMethod(cancellationTokenSource.Token);
        }
    }
    

    【讨论】:

    猜你喜欢
    • 2015-04-22
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2011-12-25
    • 1970-01-01
    相关资源
    最近更新 更多