编程语言
首页 > 编程语言> > c#-Parallel.ForEach中的Mock方法始终返回null

c#-Parallel.ForEach中的Mock方法始终返回null

作者:互联网

我有以下代码:

public int LoadFilesAndSaveInDatabase(string filesPath)
{
    var calls = new ConcurrentStack<GdsCallDto>();

    var filesInDirectory = this._directoryProxy.GetFiles(filesPath);
    if (filesInDirectory.Any())
    {
        Parallel.ForEach(filesInDirectory, file =>
        {
            var lines = this._fileProxy.ReadAllLines(file, Encoding.Unicode);
            if (lines.Any())
            {
                // Reads the file and setup a new DTO.
                var deserializedCall = this._fileManager.DeserializeFileContent(lines, Path.GetFileName(file));

                // Insert the DTO in the database.
                this._gdsCallsData.InsertOrUpdateGdsCall(deserializedCall);

                // We keep track of the dto to count the number of restored items.
                calls.Push(deserializedCall);
            }
        });
    }
    return calls.Count;
}

我有以下单元测试:

[TestMethod]
public void ShouldLoadFilesAndSaveInDatabase()
{
    // Arrange
    var path = RandomGenerator.GetRandomString(56);
    var encoding = Encoding.Unicode;
    var fileNameEnvironment = RandomGenerator.GetRandomString();
    var fileNameModule = RandomGenerator.GetRandomString();
    var fileNameRecordLocator = RandomGenerator.GetRandomString(6);
    var fileNameTimestamp = RandomGenerator.GetRandomDateTime().ToString("O").Replace(':', 'o');

    // We simulate the presence of 4 files.
    var files = new List<string>
    {
        RandomGenerator.GetRandomString(255),
        RandomGenerator.GetRandomString(255),
        RandomGenerator.GetRandomString(255),
        RandomGenerator.GetRandomString(255)
    }.ToArray();

    var expectedResult = 4;

    this._directoryProxy.Expect(d => d.GetFiles(path))
        .Return(files);

    this._fileProxy.Expect(f => f.ReadAllLines(path, encoding))
        .Return(files).Repeat.Times(files.Length);

    // Act
    var result = this._databaseReloadManager.LoadFilesAndSaveInDatabase(path);

    // Assert
    Assert.AreEqual(result, expectedResult);
    this._directoryProxy.AssertWasCalled(d => d.GetFiles(path));
    this._fileProxy.AssertWasCalled(f => f.ReadAllLines(path, Encoding.Unicode));
}

问题在以下行中:

var lines = this._fileProxy.ReadAllLines(file, Encoding.Unicode);

即使我设置了期望值和返回值,但在运行单元测试时,它始终返回null.

我正在使用Rhino.Mocks,它在其他地方也可以正常工作,但不在那儿.

我在这里看了一些讨论,但没有一个有帮助.可能是由于使用Parallel.ForEach吗?有没有办法做这样的模拟?

如果您需要其他任何信息,请告诉我.

解决方法:

我认为并行化没有问题.看来您的问题与Rhino Mock的代理实例设置有关.

确保传递给ReadAllLines的参数与在生产代码中运行时所调用的参数相同.

this._fileProxy.Expect(f => f.ReadAllLines(path, encoding))
        .Return(files).Repeat.Times(files.Length);

例如,如果您设置了不同的路径,并且在执行测试时该路径的值不同,那么您可能会看到NULL.但是,如果没有在代码中看到完整的安装程序/构造函数,就很难说出来.还要检查随机生成器,看看每次都使用了什么.

以下是我整理并为我工作的内容.
工作意味着我不会因以下原因而得到NULL:

var lines = this._fileProxy.ReadAllLines(file, Encoding.Unicode);
//some dummy code so I can compile
public interface IProxyDir
{
    IEnumerable<string> GetFiles(string path);
}

public class GdsCallDto
{
}

public class Proxy : IProxyDir
{
    public IEnumerable<string> GetFiles(string path)
    {
        throw new NotImplementedException();
    }
}

public interface IFileDir
{
    IEnumerable<string> ReadAllLines(string path, Encoding encoding);
}

public class FileProxy : IFileDir
{
    public IEnumerable<string> ReadAllLines(string path, Encoding encoding)
    {
        throw new NotImplementedException();
    }
}

public interface IFileMgr
{
    string DeserializeFileContent(IEnumerable<string> lines, string content);
}

public class FileMgr : IFileMgr
{
    public string DeserializeFileContent(IEnumerable<string> lines, string content)
    {
        throw new NotImplementedException();
    }
}

//system under test
public class Sut
{
    private IProxyDir _directoryProxy;
    private IFileDir _fileProxy;
    private IFileMgr _fileManager;

    public Sut(IProxyDir proxyDir,  IFileDir fileProxy, IFileMgr mgr)
    {
        _fileManager = mgr;
        _directoryProxy = proxyDir;
        _fileProxy = fileProxy;
    }

    public int LoadFilesAndSaveInDatabase(string filesPath)
    {
        var calls = new ConcurrentStack<GdsCallDto>();

        var filesInDirectory = this._directoryProxy.GetFiles(filesPath);
        if (filesInDirectory.Any())
        {
            Parallel.ForEach(filesInDirectory, file =>
            {
                var lines = this._fileProxy.ReadAllLines("ssss", Encoding.Unicode);

                if (lines.Any())
                {
                    // Reads the file and setup a new DTO.
                    var deserializedCall = this._fileManager.DeserializeFileContent(lines, Path.GetFileName("file"));

                    // Insert the DTO in the database.
                    //this._gdsCallsData.InsertOrUpdateGdsCall(deserializedCall);

                    // We keep track of the dto to count the number of restored items.
                    //calls.Push(deserializedCall);
                }
            });
        }

        return 1;
    }
}

样品单元测试

[TestClass]
public class UnitTest1
{
    private IProxyDir _directoryProxy;
    private IFileDir _fileProxy;
    private IFileMgr _fileMgr;

    private Sut _sut;

    public UnitTest1()
    {
        _directoryProxy = MockRepository.GenerateMock<IProxyDir>();
        _fileProxy = MockRepository.GenerateMock<IFileDir>();
        _fileMgr = MockRepository.GenerateMock<IFileMgr>();
    }

    [TestMethod]
    public void ShouldLoadFilesAndSaveInDatabase()
    {
        // Arrange
        var path = RandomGenerator.GetRandomString(56);
        var encoding = Encoding.Unicode;
        var fileNameEnvironment = RandomGenerator.GetRandomString(5);
        var fileNameModule = RandomGenerator.GetRandomString(5);
        var fileNameRecordLocator = RandomGenerator.GetRandomString(6);
        var fileNameTimestamp = RandomGenerator.GetRandomDateTime().ToString("O").Replace(':', 'o');

        // We simulate the presence of 4 files.
        var files = new List<string>
        {
            RandomGenerator.GetRandomString(255),
            RandomGenerator.GetRandomString(255),
            RandomGenerator.GetRandomString(255),
            RandomGenerator.GetRandomString(255)
        }.ToArray();

        var expectedResult = 4;

        this._directoryProxy.Expect(d => d.GetFiles(path))
            .Return(files);

        this._fileProxy.Expect(f => f.ReadAllLines(path, encoding))
    .Return(files).Repeat.Times(files.Length);

        _sut = new Sut(_directoryProxy, _fileProxy, _fileMgr);

        // Act
        var result = this._sut.LoadFilesAndSaveInDatabase(path);

        // Assert
        Assert.AreEqual(result, expectedResult);
        this._directoryProxy.AssertWasCalled(d => d.GetFiles(path));
        this._fileProxy.AssertWasCalled(f => f.ReadAllLines(path, Encoding.Unicode));
    }

}

internal class RandomGenerator
{
    public static string GetRandomString(int number)
    {
        return "ssss";
    }

    public static DateTime GetRandomDateTime()
    {
        return new DateTime();
    }
}

标签:parallel-foreach,unit-testing,c,rhino-mocks
来源: https://codeday.me/bug/20191027/1940671.html