I am having a static async cache for contacts list. Inside of the cache I am calling my repository to get data from backend. I want to mock ContactsRepository, but I need to pass repository as a parameter and use dependency injection.
According to the documentation it won't work, because i need an instance of class to use dependency injection.
public interface IContactsCache
{
Task<List<Contact>> GetContactsAsync(int inst, CancellationToken ct);
}
public class ContactsCache : IContactsCache
{
private static readonly object _syncRoot = new object();
private static readonly Dictionary<int, Task<List<Contact>>> _contactsTasks = new Dictionary<int, Task<List<Contact>>>();
public static Task<List<Contact>> GetContactsAsync(int inst)
{
return GetContactsAsync(inst, CancellationToken.None);
}
public static async Task<List<Contact>> GetCodeValuesAsync(int inst, CancellationToken ct)
{
Task<List<Contact>> task;
lock (_syncRoot)
{
if (_contactsTasks.ContainsKey(inst) && (_contactsTasks[inst].IsCanceled || _contactsTasks[inst].IsFaulted))
{
_contactsTasks.Remove(inst);
}
if (!_contactsTasks.ContainsKey(inst))
{
_contactsTasks[inst] = Task.Run(async () =>
{
using (var rep = new ContactsRepository())
{
return await rep.LoadAsync(inst, ct).ConfigureAwait(false);
}
});
}
task = _contactsTasks[inst];
}
var res = await task.ConfigureAwait(false);
lock (_syncRoot)
{
return res != null ? res.ToList() : null;
}
}
Task<List<CodeValue>> IContactsCache.GetContactsAsync(int inst, CancellationToken ct)
{
return GetContactsAsync(inst, ct);
}
}
At the end I expect to have this kind of usage, but I can't figure out how to change cache class or any king of other help will be very helpful.
[TestMethod]
public async void GetContactAsync_WhenCalled_ReturnCodeValuesCache()
{
var expected = new List<Contact>
{
new Contact() {Instance = 1, Name = "Test" }
};
var mock = new Mock<IContactsRepository>()
.Setup(x => x.LoadAsync(It.IsAny<int>(), CancellationToken.None))
.ReturnsAsync(new List<Contact>(expected));
var actual = await ContactsCache.GetContactsAsync(It.IsAny<int>(), CancellationToken.None);
CollectionAssert.AreEqual(actual, expected);
}
But it can't work and I don't know how to properly write unit test.
I have a lot of such caches where I am using such repositories. Are there any standart or best practise how to unit test static async caches and how to mock repository in this case?
Aucun commentaire:
Enregistrer un commentaire