Может быть, вы можете изменить поле:
private readonly DiscordSocketClient client;
в ListManager
только на гильдии, то есть:
private readonly IReadOnlyCollection<IGuild> guilds;
, а затем, конечно, соответственно изменить его конструктор.
Тогда вы просто делаете:
guilds.First().Roles.Where(r => r.Name.Equals(roleName)).FirstOrDefault()
или эквивалентно:
guilds.First().Roles.FirstOrDefault(r => r.Name == roleName)
Я думаю, что вы должны быть в состоянии передать client.Guilds
при создании ListManager
из вашего "реального" кода.Это из-за хорошей ковариации типа IReadOnlyCollection<out T>
.
В своем тесте вы можете просто передать new[] { guildMoq1.Object, guildMoq2.Object, }
, где guildMoq1
и т. Д. - это Mock<IGuild>
, где вы настроили .Roles
по желанию (опять же, вы можете использовать new [] { ... }
для настройки .Roles
).
Редактировать:
Возможно в ListManager
используйте Func<>
:
private readonly Func<IReadOnlyCollection<IGuild>> getGuilds;
и тот же Func<>
в подписи конструктора.Тогда этот аргумент конструктора может быть задан как:
() => client.Guilds
из вашего "реального кода".Таким образом, вы можете создать свой ListManager
уже в то время, когда client.Guilds
еще не готов к запросу.Ссылка client
будет «захвачена» в Func<>
(семантика замыкания).
В тесте вы можете использовать:
() => new[] { guildMoq1.Object, guildMoq2.Object, }
, где guildMoq1
и т. Д.как раньше?
Конечно, строка в ListManager
теперь будет выглядеть так:
getGuilds().First().Roles.FirstOrDefault(r => r.Name == roleName)