Я думаю, что вы на правильном пути, поскольку вы абстрагировали связь с базой данных и зависимости ASP.NET от своих модульных тестов. Не волнуйтесь, что вы не можете проверить все в своих тестах. В вашем приложении всегда будут строки кода, которые невозможно проверить. GetIdentity
является хорошим примером. Где-то в вашем приложении вам нужно взаимодействовать с API, специфичным для фреймворка, и этот код не может быть охвачен вашими юнит-тестами.
Хотя, возможно, еще есть возможности для улучшения. Хотя непроверенный GetIdentity
не является проблемой, тот факт, что он на самом деле вызывается приложением. Он просто висит там, ожидая, что кто-то случайно позвонит. Так почему бы не абстрагироваться от создания идентичностей. Например, создайте абстрактную фабрику, которая знает, как получить правильную идентичность для текущего контекста. Вы можете внедрить эту фабрику, вместо того, чтобы вводить саму личность. Это позволяет вам иметь реализацию, определенную около корня композиции приложения и вне зоны досягаемости остальной части приложения. Кроме того, код более четко передает происходящее. Никто не должен спрашивать «какую личность я на самом деле получаю?», Потому что это будет понятно по методу фабрики, которую они вызывают.
Вот пример:
public interface IIdentityProvider
{
// Bit verbose, but veeeery clear,
// but pick another name if you like,
MyIdentity GetIdentityForCurrentUser();
}
В вашем корне композиции вы можете реализовать это:
private sealed class AspNetIdentityProvider : IIdentityProvider
{
public MyIdentity GetIdentityForCurrentUser()
{
// here the code of the MyIdentity.GetIdentity() method.
}
}
В качестве хитрости я иногда заставляю свои тестовые объекты реализовывать как фабрику, так и продукт, просто для удобства во время модульного тестирования. Например:
private sealed class FakeMyIdentity
: FakeMyIdentity, IIdentityProvider
{
public MyIdentity GetIdentityForCurrentUser()
{
// just returning itself.
return this;
}
}
Таким образом, вы можете просто добавить FakeMyIdentity в конструктор, который ожидает IIdentityProvider. Я обнаружил, что это не жертвует удобочитаемостью тестов (что важно).
Конечно, вы хотите иметь как можно меньше кода в AspNetIdentityProvider, потому что вы не можете его протестировать (автоматически). Также убедитесь, что ваш класс MyIdentity
не имеет никакой зависимости от каких-либо специфичных для фреймворка частей. Если это так, то вам также необходимо это абстрагировать.
Надеюсь, это имеет смысл.