Мок с заданием ждут
Поскольку я преобразовал свои методы WCF в Async, мои модульные тесты потерпели неудачу, и я не могу понять правильный синтаксис, чтобы заставить их работать.
Класс прокси-сервера Cllient
public interface IClientProxy
{
Task DoSomething(CredentialDataList credentialData, string store);
}
класс обслуживания
public class CredentialSync : ICredentialSync
{
private ICredentialRepository _repository;
private IClientProxy _client;
public CredentialSync()
{
this._repository = new CredentialRepository();
this._client = new ClientProxy();
}
public CredentialSync(ICredentialRepository repository, IClientProxy client)
{
this._repository = repository;
this._client = client;
}
public async Task Synchronise(string payrollNumber)
{
try
{
if (string.IsNullOrEmpty(payrollNumber))
{
.... some code
}
else
{
CredentialDataList credentialData = new CredentialDataList();
List<CredentialData> credentialList = new List<CredentialData>();
// fetch the record from the database
List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber);
var pinData = this._repository.GetCredentialPinData(payrollNumber);
// get the stores for this employee
var storeList = data.Where(a => a.StoreNumber != null)
.GroupBy(a => a.StoreNumber)
.Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray();
var credential = this.ExtractCredentialData(data, pinData, payrollNumber);
credentialList.Add(credential);
credentialData.CredentialList = credentialList;
foreach (var store in storeList)
{
//this line causes an Object reference not set to an instance of an object error
await _client.DoSomething(credentialData, store.StoreNumber);
}
}
}
catch (Exception ex)
{
throw new FaultException<Exception>(ex);
}
}
Класс тестирования
/// </summary>
[TestClass]
public class SynchTest
{
private Mock<ICredentialRepository> _mockRepository;
private Mock<IClientProxy> _mockService;
[TestInitialize]
public void Setup()
{
... some setups for repository which work fine
}
[TestMethod]
public async Task SynchroniseData_WithOneEmployee_CallsReplicateService()
{
this._mockService = new Mock<IClientProxy>();
this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()));
// arrange
string payrollNumber = "1";
CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object);
// act
await service.Synchronise(payrollNumber);
// assert
this._mockService.VerifyAll();
}
Ошибка при вызове ClientProxy.DoSomething
:
Ссылка на объект не установлена в экземпляр объекта
Параметры оба хороши.
Если я конвертирую свой метод ClientProxy.DoSomething
в синхронный метод
(public void DoSomething(...)
) код работает нормально, но мне нужно, чтобы это называлось асинхронно
Ответы
Ответ 1
DoSomething
возвращает null
вместо возврата Task
, и вы получаете исключение при его ожидании. Вы должны указать при построении макета, что он должен вернуть Task
.
В этом случае кажется, что вы можете просто вернуть уже выполненную задачу, используя Task.FromResult
поэтому настройка макета должна выглядеть следующим образом:
this._mockService.Setup(...).Returns(Task.FromResult(false));
Начиная со следующей версии .Net(4.6) вы можете использовать Task.CompletedTask
следующим образом:
this._mockService.Setup(...).Returns(Task.CompletedTask);
Ответ 2
Вы можете уменьшить количество помех в коде, используя ReturnsAsync
this._mockService.Setup(...).ReturnsAsync(false)
;
Таким образом вы можете удалить часть Task.FromResult
кода
Ответ 3
Я думаю, что вам нужно вернуть Task
из макета DoSomething
this._mockService.Setup(x => x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()))
.Returns(Task.FromResult<int>(0));