Поблочное тестирование и проверяющий значение частной переменной

Можно ли использовать Службы преобразования данных, чтобы сделать задание? Это обеспечивает все виды инструментов болта вместе для того, чтобы сделать такого рода вещь.

можно загрузить пакет функций SQL Server 2005 года с веб-сайта Microsoft здесь

48
задан Ruben Bartelink 9 October 2011 в 07:18
поделиться

5 ответов

The quick answer is that you should never, ever access non-public members from your unit tests. It totally defies the purpose of having a test suite, since it locks you into internal implementation details that you may not want to keep that way.

The longer answer relates to what to do then? In this case, it is important to understand why the implementation is as it is (this is why TDD is so powerful, because we use the tests to specify the expected behavior, but I get the feeling that you are not using TDD).

In your case, the first question that comes to mind is: "Why are the IAuditable objects added to the internal list?" or, put differently, "What is the expected externally visible outcome of this implementation?" Depending on the answer to those questions, that's what you need to test.

If you add the IAuditable objects to your internal list because you later want to write them to an audit log (just a wild guess), then invoke the method that writes the log and verify that the expected data was written.

If you add the IAuditable object to your internal list because you want to amass evidence against some kind of later Constraint, then try to test that.

If you added the code for no measurable reason, then delete it again :)

The important part is that it is very beneficial to test behavior instead of implementation. It is also a more robust and maintainable form of testing.

Don't be afraid to modify your System Under Test (SUT) to be more testable. As long as your additions make sense in your domain and follow object-oriented best practices, there are no problems - you would just be following the Open/Closed Principle.

92
ответ дан 26 November 2019 в 18:42
поделиться

Если я не ошибаюсь, вы действительно хотите проверить, что он добавляет элементы в список только тогда, когда их можно привести к IAuditable . Итак, вы можете написать несколько тестов с такими именами методов, как:

  • NotIAuditableIsNotSaved
  • IAuditableInstanceIsSaved
  • IAuditableSubclassInstanceIsSaved

... и так далее.

Проблема в том, что, как вы заметили, с учетом кода в вашем вопросе вы можете сделать это только косвенно - только проверив частный член insertItems IList (путем отражения или путем добавления свойства с единственной целью тестирования) или вставив список в class:

public class ClassToBeTested
{
    private IList _InsertItems = null;

    public ClassToBeTested(IList insertItems) {
      _InsertItems = insertItems;
    }
}

Тогда просто протестировать:

[Test]
public void OnSave_Adds_Object_To_InsertItems_Array()
{
     Setup();

     List<object> testList = new List<object>();
     myClassToBeTested     = new MyClassToBeTested(testList);

     // ... create audiableObject here, etc.
     myClassToBeTested.OnSave(auditableObject, null);

     // Check auditableObject has been added to testList
}

Внедрение - это наиболее перспективное и ненавязчивое решение, если только у вас нет причин полагать, что список будет ценной частью вашего общедоступного интерфейса (в этом случае добавление свойства может быть лучше - и, конечно, внедрение свойств также совершенно законно ). Вы даже можете сохранить конструктор без аргументов, который обеспечивает реализацию по умолчанию (new List ()).

Это действительно хорошая практика; Это может показаться вам слишком сложным, учитывая, что это простой класс, но только тестируемость того стоит. Затем, вдобавок ко всему, если вы найдете другое место, где хотите использовать класс, это будет вишенкой на торте, поскольку вы не будете ограничены использованием IList (не то чтобы позже потребовалось много усилий, чтобы внести изменения. ).

но одна проверяемость того стоит. Затем, вдобавок ко всему, если вы найдете другое место, где хотите использовать класс, это будет вишенкой на торте, поскольку вы не будете ограничены использованием IList (не то чтобы позже потребовалось много усилий, чтобы внести изменения. ).

но одна проверяемость того стоит. Затем, вдобавок ко всему, если вы найдете другое место, где хотите использовать класс, это будет вишенкой на торте, поскольку вы не будете ограничены использованием IList (не то чтобы позже потребовалось много усилий, чтобы внести изменения. ).

1
ответ дан 26 November 2019 в 18:42
поделиться

Вы не должны проверять список, в который был добавлен элемент. Если вы это сделаете, вы будете писать модульный тест для метода Add из списка, а не тест для вашего кода. Просто проверьте возвращаемое значение OnSave; это действительно все, что вы хотите протестировать.

Если вас действительно беспокоит возможность добавления, вычеркните его из уравнения.

Изменить:

@TonE: После прочтения ваших комментариев я бы сказал, что вы можете захотеть чтобы изменить текущий метод OnSave, чтобы вы знали об ошибках. Вы можете создать исключение в случае сбоя приведения и т. Д. Затем вы можете написать модульный тест, который ожидает и исключение, а другой - нет.

6
ответ дан 26 November 2019 в 18:42
поделиться

Я бы сказал, что «лучший способ» - это проверить что-то важное с объектом, который изменился сейчас, когда он сохранил сущность в списке.

Другими словами, какое поведение изменилось в классе теперь, когда он сохранил его, и проверка этого поведения. Хранилище - это деталь реализации.

Тем не менее, это не всегда возможно.

2
ответ дан 26 November 2019 в 18:42
поделиться

Если список является деталью внутренней реализации (а так и есть), то вам не следует его тестировать.

Хороший вопрос: какого поведения можно ожидать? если товар был добавлен в список? Это может потребовать другого метода для его запуска.

    public void TestMyClass()
    {
        MyClass c = new MyClass();
        MyOtherClass other = new MyOtherClass();
        c.Save(other);

        var result = c.Retrieve();
        Assert.IsTrue(result.Contains(other));
    }

В этом случае я утверждаю, что правильное, внешне видимое поведение состоит в том, что после сохранения объекта он будет включен в полученную коллекцию.

Если результат заключается в том, что в будущем переданный объект должен иметь вызовы к нему при определенных обстоятельствах, тогда у вас может быть что-то вроде этого (простите, псевдо-API):

    public void TestMyClass()
    {
        MyClass c = new MyClass();
        IThing other = GetMock();
        c.Save(other);

        c.DoSomething();
        other.AssertWasCalled(o => o.SomeMethod());
    }

В обоих случаях вы тестируете внешне видимое поведение класса, а не внутренняя реализация.

1
ответ дан 26 November 2019 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: