Сразу, я сказал бы, что "Вы спрашиваете слишком много". Из того, что небольшой опыт, который я имел, я рекомендовал бы читать некоторые учебные руководства или заставить книгу или по directX или по OpenGL начинаться. Пойти немного ниже, чем это было бы довольно сложно. Большинство книг, которые я видел в OGL или DX, имеет довольно хорошие введения, которые объясняют, что делают функции/классы.
, Как только Вы приобретаете навык одного из них, Вы могли всегда закапывать к библиотекам для наблюдения то, что точно они делают для понижений.
Или, если Вы действительно, абсолютно ДОЛЖЕН учиться, САМЫЙ НИЗКИЙ уровень... прочитал книгу в вышеупомянутом сообщении.
Никогда не тестируйте имитацию. Тестируемый класс всегда должен быть реальным экземпляром класса, хотя вы можете и должны имитировать любую из его зависимостей, чтобы тестировать его изолированно.
Вы должны тестировать настоящий класс, а не фальшивый, который вы делаете для тестирования. Смысл использования интерфейса заключается в том, что он позволяет вам имитировать класс, поэтому вы можете использовать его в тестах с другими соавторами.
Чтобы протестировать класс, вы должны иметь возможность передать имитацию базы данных и утверждать, что вызовы, которые вы ожидали сделать в базе данных, действительно происходят, когда вы вызываете методы в своем классе репозитория.
Вот хорошее введение в насмешку и тестирование в C #:
http: //refact.blogspot . com / 2007/01 / mock-objects-and-rhino.html
Я объясню, что я делаю, почему и сколько пробега у меня получается.
Во-первых, я делаю именно то, что делаете вы , относительно ваших репозиториев. Несмотря на некоторые различия в пространстве имен, я тоже делаю это:
With my fake UserRepository, я также просто создаю и заполняю частную коллекцию IEnumerable
(которая представляет собой List
). Зачем мне это? Я использую этот репозиторий для своей начальной повседневной разработки (потому что это быстро -> нет доступа к базе данных == быстро!). Затем я заменяю поддельные репозитории на репозитории sql (т.е. меняю свою инъекцию зависимостей (ооооооо!)). Вот почему существует этот класс / пространство имен, в отличие от использования Mocks в моем модульном тесте для «поддельных» материалов. (Это случается, но при других обстоятельствах.)
Я использую LinqToSql в своем UserRepository на моем сервере sql. Что касается вашего вопроса, это безразлично, что я использую LinqToSql ... это может быть любая другая оболочка базы данных. Здесь важно то, что есть стороннее нечто , с которым я интегрирую .
Хорошо, теперь мне нужно убедиться в двух вещах
Во-первых, большинство людей не создают модульный тест для подделки. Это поддельный кусок какашки, так зачем тратить энергию? Верно - за исключением того, что я использую этот фальшивый кусок дерьма в своей повседневной разработке (см. Мою болтовню об этом выше). Поэтому я быстро создаю несколько базовых модульных тестов. ПРИМЕЧАНИЕ. В моих глазах это модульные тесты, хотя это классы репозитория
. Почему? Они не интегрируют со сторонними организациями / инфраструктурой.
Затем (наконец я перехожу к сути) я провожу отдельный тестовый класс, который является тестом интеграции. Это модульный тест, который интегрируется с чем-то вне системы. Это может быть настоящий твиттер API. Это может быть настоящий S3 Amazon api. Обратите внимание, что я использовал слово real . Вот здесь ключ. Я интегрируюсь с реальной службой ВНЕ моей. Таким образом -> это медленно. Каждый раз, когда мне нужно оставить свой компьютер для некоторых данных, это ' s называется объединением , и вы автоматически предполагаете (и ожидаете), что это будет медленно.
Итак, здесь я интегрирую с базой данных.
(Нет, скажите, пожалуйста, не троллите это с помощью дерзкие предложения, что у вас есть база данных на том же компьютере ... вы покидаете свой «мир» ПРИЛОЖЕНИЯ).
Вау. это какой-то роман о войне и мире ... время для жестких действий, кода пощечины. Давайте принесем его!
namespace MyProject.Tests.Repositories.SqlServer
{
// ReSharper disable InconsistentNaming
[TestClass]
public class UserRepositoryTests : TestBase
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
// Arrange.
// NOTE: this method is inherited from the TestBase abstract class.
// Eg. protected IUserRepository =
// new MyProject.Respositories.SqlServer
// .UserRespository(connectionString);
InitializeSqlServerTestData();
}
[TestMethod]
public void GetFirst20UsersSuccess()
{
// Act.
var users = _users.GetUsers()
.Take(20)
.ToList();
// Assert.
Assert.IsNotNull(users);
Assert.IsTrue(users.Count() > 0);
}
}
}
Хорошо, давайте пройдемся по этому щенку.
Во-первых, это с помощью Microsoft Unit Testing - встроенного в VS2010 Beta2 или с выпуском Team Foundation VS2008 (или какой бы там ни была эта версия ... i просто установите копию, которую приобрела наша работа).
Во-вторых, всякий раз, когда класс инициализируется впервые (будь то один тест или несколько), он создает контекст
. В моем случае это мой репозиторий пользователей Sql Server, который будет использовать контекст LinqToSql. (Ваш будет контекстом EF). Это часть TDD Arrange .
В-третьих, я вызываю метод -> это часть TDD Act .
Наконец, я проверяю, вернулся ли я что я ожидал -> это Assert часть TDD.
А как насчет обновления БД?
Просто следуйте той же схеме, за исключением того, что вы можете заключить вызывающий код в транзакцию и откатить ее. В противном случае вы можете получить 100 строк данных, которые могут быть одинаковыми. Обратной стороной этого? Любые поля identity
не будут иметь красивую и красивую последовательность нумерации (потому что при откате будет «использоваться» этот номер). Не имеет смысла? не волнуйся. это продвинутый совет, я подумал, что добавлю, чтобы проверить вас, но это означает, что для этого адски длинного поста он означает, что приседайте на корточки.
так что ... э ... да. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачивать и поливать меня грязью, но мне это вроде как нравится, и я надеюсь, что это поможет тебе.
HTH.
s строк данных, которые могут быть одинаковыми. Обратной стороной этого? Любые поля identity
не будут иметь красивую и красивую последовательность нумерации (поскольку при откате будет «использоваться» этот номер). Не имеет смысла? не волнуйся. это продвинутый совет, я подумал, что добавлю, чтобы проверить вас, но это означает, что для этого адски длинного поста он означает, что приседайте на корточки.
так что ... э ... да. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачивать и поливать меня грязью, но мне это вроде как нравится, и я надеюсь, что это поможет тебе.
HTH.
s строк данных, которые могут быть одинаковыми. Обратной стороной этого? Любые поля identity
не будут иметь красивую и красивую последовательность нумерации (потому что при откате будет «использоваться» этот номер). Не имеет смысла? не волнуйся. это продвинутый совет, я подумал, что добавлю, чтобы проверить вас, но это означает, что для этого адски длинного поста он означает, что приседайте на корточки
так что ... э ... да. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачивать и поливать меня грязью, но мне это вроде как нравится, и я надеюсь, что это поможет тебе.
HTH.
это продвинутый совет, я подумал, что добавлю, чтобы проверить вас, но это означает, что для этого чертовски длинного поста это означает, что он должен сидеть на корточках для этого адски длинного поста. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачивать и поливать меня грязью, но мне это вроде как нравится, и я надеюсь, что это поможет тебе.HTH.
это продвинутый совет, я подумал, что добавлю, чтобы проверить вас, но это означает, что для этого чертовски длинного поста он должен сидеть на корточках.так что ... э ... да. это то, чем я занимаюсь. Не знаю, будут ли боги программирования на этих форумах переворачивать и поливать меня грязью, но мне это вроде как нравится, и я надеюсь, что это поможет тебе.
HTH.