-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Open
Labels
Description
Good evening.
How do I mock the method AddCondition
from ITransaction
?
My class:
public class SampleRedisRepository
{
private const string cFIELD_STATUS = "STATUS";
private const string cFIELD_STATUS_TIME = "STATUS_TIME";
private const string cFIELD_STATUS_DESCRIPTION = "STATUS_DESCRIPTION";
private const string cPATH = nameof(SampleRedisRepository);
private const string cFIELD_REQUEST_TYPE = "REQUEST_TYPE";
private const string cFIELD_CREATION_TIME = "CREATION_TIME";
private const string cFIELD_STATUS_HISTORY = "STATUS_HISTORY";
private readonly int _redisDbNumber;
private readonly IDatabase _database;
private readonly ILogger<SampleRedisRepository> _logger;
public SampleRedisRepository(IDatabase database, ILogger<SampleRedisRepository> logger, int redisDbNumber)
{
_database = database ?? throw new ArgumentNullException(nameof(database));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_redisDbNumber = redisDbNumber;
}
public void Create<TRequest>(Guid requestId) where TRequest : class
{
var requestType = typeof(TRequest).FullName;
var key = CreateKey(requestId);
var redisTime = GetRedisTime();
var tran = _database.CreateTransaction();
var crKeyNotExists = tran.AddCondition(Condition.KeyNotExists(key));
tran.HashSetAsync(key, new HashEntry[] {
new HashEntry(cFIELD_REQUEST_TYPE, requestType),
new HashEntry(cFIELD_CREATION_TIME, redisTime),
new HashEntry(cFIELD_STATUS, $"{ERequestStatus.InProgress}"),
new HashEntry(cFIELD_STATUS_TIME, redisTime),
new HashEntry(cFIELD_STATUS_DESCRIPTION, "created"),
});
if (tran.Execute())
{
_logger.LogDebug($"Request Id:{requestId} created.");
return;
}
if (!crKeyNotExists.WasSatisfied)
throw new InvalidOperationException($"Request Id:{requestId} already exists.");
throw new InvalidOperationException($"Error on create request Id:{requestId}.");
}
private long GetRedisTime() => (long)_database.ScriptEvaluate("return redis.call('TIME')[1]");
public static RedisKey CreateKey(Guid requestId) => $"{cPATH}:{requestId}";
}
My unit test:
[Fact]
public void Create_Test()
{
int redisNumber = 2;
Guid requestId = Guid.NewGuid();
var key = SampleRedisRepository.CreateKey(requestId);
RedisResult redisTime = RedisResult.Create(123456);
var mqTransaction = new Mock<ITransaction>();
mqTransaction
.Setup(t => t.AddCondition(Condition.KeyNotExists(key)))
.Returns(????); // => PROBLEM!! How do I create an instance of ConditionResult ??
var mqDatabase = new Mock<IDatabase>();
mqDatabase
.Setup(d => d.CreateTransaction(It.IsAny<object?>()))
.Returns(mqTransaction.Object);
mqDatabase
.Setup(d => d.ScriptEvaluate("return redis.call('TIME')[1]", It.IsAny<RedisKey[]?>(), It.IsAny<RedisValue[]?>(), It.IsAny<CommandFlags>()))
.Returns(redisTime);
var initialData = new Dictionary<string, string>()
{
{ "Redis:DbNumber", redisNumber.ToString() }
};
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(initialData)
.Build();
var repository = new SampleRedisRepository(mqDatabase.Object, Mock.Of<ILogger<SampleRedisRepository>>(), redisNumber);
repository.Create<SimpleClassToTest>(requestId);
mqDatabase.Verify(c => c.CreateTransaction(It.IsAny<object?>()), Times.Once());
mqTransaction.Verify(c => c.HashSetAsync(
key,
It.Is<HashEntry[]>(he => he.Any(
h => h.Name.Equals("STATUS")
&& h.Value.Equals($"{ERequestStatus.InProgress}")
&& h.Name.Equals("REQUEST_TYPE")
&& h.Value.Equals(typeof(SimpleClassToTest).FullName)
&& h.Name.Equals("STATUS_DESCRIPTION")
&& h.Value.Equals("created")
&& h.Name.Equals("STATUS_TIME")
&& h.Value.Equals(redisTime)
)),
It.IsAny<CommandFlags>()), Times.Once());
}
I cannot create an instance of ConditionResult
because the constructor is internal
. See line 827 of Condition.cs
Many thanks.
kmcclellan