Michael Foster Michael Foster - 3 months ago 7
C# Question

Condense code: SetupSequence returning different values on successive calls

I am testing a method that calls other methods. I have a working test that uses this method to generate my mocked connection object:

private Mock<IDatabaseConnection> MockOutGetControlDocInfoData()
{
Mock<IDatabaseConnection> mockConn = new Mock<IDatabaseConnection>();
List<Mock<IDbCommand>> mockCmds = new List<Mock<IDbCommand>>();
List<long> vals = new List<long>() { 2, 2, 2, 2, 10, 2, 2, 2, 2, 2 };
foreach (long val in vals)
{
mockCmds.Add(CreateMockCmdObjectWithReturnValue(val));
}
mockConn.SetupAllProperties();
mockConn.Setup(c => c.Conn.ConnectionString).Returns("What the heck.");
mockConn.SetupSequence(c => c.CreateCommand(It.IsAny<string>()))
.Returns(mockCmds[0].Object)
.Returns(mockCmds[1].Object)
.Returns(mockCmds[2].Object)
.Returns(mockCmds[3].Object)
.Returns(mockCmds[4].Object)
.Returns(mockCmds[5].Object)
.Returns(mockCmds[6].Object)
.Returns(mockCmds[7].Object)
.Returns(mockCmds[8].Object)
.Returns(mockCmds[9].Object);
return mockConn;
}


I'm not pleased with the SetupSequence Returns, which seems like it ought to be part of a loop, but I don't know how to put more than one Returns into the SetupSequence. Any idea for improvement?

For now at least, I'm fine with manually creating my list of test values.

It shouldn't be relevant, but I can provide the
CreateMockCmdObjectWithReturnValue
code if needed.

Answer
var sequence = mockConn.SetupSequence(c => c.CreateCommand(It.IsAny<string>()));
foreach (var cmd in mockCmds)
{
   sequence = sequence.Returns(cmd.Object);
}
Comments