在模拟中测试多线程服务方法

Yur*_*han 3 c# unit-testing moq

例如,我想测试以下事实:如果我给他n个来自不同线程的数据块,则我的多线程方法将调用存储库方法n次。当然,模拟不是线程安全的,甚至不应该是这样。

[Test]
public void CanSaveCustomersInParallel()
{
    var customers = new List<List<Customer>>
                        {
                            new List<Customer>
                                {
                                    new Customer {FirstName = "FirstName1"},
                                    new Customer {FirstName = "FirstName2"}
                                },
                            new List<Customer>
                                {
                                    new Customer {FirstName = "FirstName3"},
                                    new Customer {FirstName = "FirstName4"}
                                }
                        };
    _serviceCustomers.ParallelSaveBatch(customers);
    _repoCustomers
        .Verify(x => x.SaveBatch(It.IsAny<List<Customer>>()), Times.Exactly(2));
}
Run Code Online (Sandbox Code Playgroud)

当然,该测试有时会失败,有时不会失败。但这本质上是错误的。您能建议我如何重写吗?

Yur*_*han 5

好吧,下一个存根做到了:

internal class ServiceStub: Service<DummyEntity>
{
    private int _count;

    public int Count
    {
        get { return _count; }
    }

    public override void SaveBatch(IEnumerable<object> entities)
    {
       lock(this)
       {
           _count++;
       }
    }

    public ServiceStub(IRepository<DummyEntity> repository):base(repository)
    {
        _count = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

单元测试看起来是这样:

    [Test]
    public void CanSaveCustomersInParallel()
    {
        var service = new ServiceStub(new DummyRepository());
        var customers = new List<List<Customer>>
                            {
                                new List<Customer>
                                    {
                                        new Customer {FirstName = "FirstName1"},
                                        new Customer {FirstName = "FirstName2"}
                                    },
                                new List<Customer>
                                    {
                                        new Customer {FirstName = "FirstName3"},
                                        new Customer {FirstName = "FirstName4"}
                                    }
                            };
        service.ParallelSaveBatch(customers);
        Assert.AreEqual(service.Count, customers.Count);
    }
Run Code Online (Sandbox Code Playgroud)