Макет метода параллельно.ForEach всегда возвращает 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.Издевается, он прекрасно работает в другом месте, но не там.
Я посмотрел здесь несколько дискуссий, но ни одна из них не помогла. Может быть, это связано с использованием параллельного.По каждому элементу? Есть ли способ сделать это такая насмешка?Если вам нужна какая-либо другая информация, пожалуйста, дайте мне знать.
2 ответа:
Я не думаю, что есть проблема с распараллеливанием. Похоже, ваша проблема связана с установкой экземпляра прокси с 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(); } }
Я мог бы избавиться от этой проблемы, вероятно, вызванной использованием случайных величин. Теперь я вызываю метод IgnoreArguments () по моему ожиданию:
this._fileProxy.Expect(f => f.ReadAllLines(path, encoding)) .Return(files).Repeat.Times(files.Length).IgnoreArguments();
Он делает трюк (то есть модульный тест успешно выполняется), но я не знаю, очень ли он элегантен.