MS Unit пример тестирования - PullRequest
       0

MS Unit пример тестирования

4 голосов
/ 12 декабря 2010

Я изо всех сил пытаюсь разобраться с юнит-тестированием. Я следовал за примерами из обеда Nerd и pro asp.net MVC framework, но как только я попробую свои собственные, быстро застрял. В качестве теста я попытался создать класс проверки, который просто использует данные для входа в систему - имя пользователя и пароль, чтобы вернуть пользователя из хранилища. Я использовал этот пример, так как довольно просто представить, какие тесты можно выполнить: Is_Password_Valid, Is_Username_Valid и т. Д.

Я слишком долго пытался разобраться с этим. Может ли кто-нибудь привести пример того, как они могут подходить к этому как к модульному тесту? Я думаю, что как только я сломаю это, я буду отсутствовать.

//Arrange
string email = "test@test.com";
string password = "test";

//Arrange
List<Customer> customer = new List<Customer>();

customer.Add(new Customer { CustomerId = 1, Email = email, Password = "best", FirstName = "test", LastName = "wods", Sex = true });
mockRepos = new Moq.Mock<ICustomerRepository>();
mockRepos.Setup(x => x.GetCustomerByPasswordUsername(email, password)).Returns(customer.First());
Authenticate auth = new Authenticate(mockRepos.Object);

//Act
var result = auth.Login(email, password);

//Assert
//this is where I start to become unstuck??????

Ответы [ 2 ]

14 голосов
/ 12 декабря 2010

Похоже, вы на правильном пути, но позвольте мне попытаться объяснить, как я буду проходить тест.

Фактическая тестируемая система (SUT) - это класс Authenticate. Вы не много рассказали об этом, поэтому я приму следующее:

Он использует экземпляр ICustomerRepository для определения существования пользователя на основе комбинации имени пользователя (электронной почты) и пароля.

Когда хранилище возвращает экземпляр Customer, учитывая комбинацию имени пользователя и пароля, метод Login возвращает true. Когда хранилище возвращает null, метод Login возвращает false.

Я буду использовать эти допущения в следующем, но если они не верны, я уверен, что вы сможете изменить тесты, чтобы они соответствовали вашему сценарию.

Тест 1: Если комбинация имени пользователя и пароля верна, Login вернет true

public void LoginWillReturnTrueForAValidUsernamePasswordCombination()
{
    string email = "test@test.com";
    string password = "test";

    //Dummy customer
    var customer = new Customer();

    //Create mock
    var mockRepos = new Moq.Mock<ICustomerRepository>();
    mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
            It.Is<string>(s => s == email), 
            It.Is<string>(s => s == password))
        .Returns(customer);

    var auth = new Authenticate(mockRepos.Object);

    //Act
    var result = auth.Login(email, password);

    //Assert
    Assert.IsTrue(result);
}

Обратите внимание на использование It.Is. По сути, макет настроен таким образом, что он будет возвращать фиктивный объект-клиент только тогда, когда электронная почта и пароль, определенные в вашем тесте, будут переданы методу GetCustomerByPasswordUsername.

Тест 2: Если комбинация имени пользователя и пароля неверна, Login вернет false

public void LoginWillReturnFalseForAnInvalidUsernamePasswordCombination()
{
    string email = "test@test.com";
    string password = "test";

    //Create mock
    var mockRepos = new Moq.Mock<ICustomerRepository>();
    mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
            It.Is<string>(s => s == email), 
            It.Is<string>(s => s == password))
        .Returns<Customer>(null);

    var auth = new Authenticate(mockRepos.Object);

    //Act
    var result = auth.Login(email, password);

    //Assert
    Assert.IsFalse(result);
}

Несмотря на то, что тесты, описанные выше, неявно тестируются, вы можете пойти дальше и написать тест, который гарантирует, что метод Login передает правильные параметры в хранилище. Такой тест может выглядеть следующим образом:

Тест 3: при входе в систему будет правильно запускаться хранилище

public void LoginWillInvokeGetCustomerByPasswordUsernameCorrectly()
{
    string email = "test@test.com";
    string password = "test";

    //Create mock
    var mockRepos = new Moq.Mock<ICustomerRepository>();
    mockRepos.Setup(x => x.GetCustomerByPasswordUsername(
            It.Is<string>(s => s == email), 
            It.Is<string>(s => s == password))
        .Returns<Customer>(null)
        .Verifiable();

    var auth = new Authenticate(mockRepos.Object);

    //Act (ignore result. We are only testing correct invocation)
    auth.Login(email, password);

    //Assert
    mockRepos.Verify();
}

Метод макета Verify создает исключение, если не были вызваны настроенные методы.

Надеюсь, это поможет. Не стесняйтесь спрашивать, если у вас есть дополнительные вопросы.

0 голосов
/ 15 декабря 2011

Если у вас есть тестируемая система, использующая API, к которому ваша SUT также добавляет прослушиватель, это также может быть немного сложнее (вы можете сделать то же самое с исполнителями и таймерами (смоделируйте оба)).

class RealAPIYouSUTUses {
      public void addListener(XXXListener l);
}

class MockAPI implements RealAPIYourSUTUses{
      public void addListener(XXXListener l) {
         this.cachedListener = l;
      }
      public XXXListener getListener() {
         return cachedListener;
      } 
}

Тогда ваш юнит-тест может проверить listesner и его взаимодействие с системой ...

class Test {
    public void test() {
        MockAPI mockAPI = new MockAPI();   
        SUT sut = new SUT(mockAPI);  

        sut.doSomething();
        //expect your listener to be added from calling doSomething....
        XXXListener l = mockApi.getListener();

        //simulate firing an event into your SUT 
        l.fireEvent(new Event("asdf"));
    }
}

Интересно, что во всем этом вы можете издеваться над Executor.java и Timer.java и ваш тест могут получить исполняемый файл, который был предоставлен исполнителю, а TimerTaks - таймеру, и вы можете запускать их по порядку и в обратном порядке, чтобы убедиться, что ваша система работает.программирование и модульное тестирование, такие как это, дают вам возможность убедиться, что интеграция между всеми вашими классами работает.

...