происходит с кодом, подобным xyz->method()
, где xyz
не является объектом и, следовательно, method
не может
Это фатальная ошибка, которая остановит сценарий (уведомление о прямой совместимости: это станет захватывающей ошибкой, начиная с PHP 7).
Чаще всего это знак что в коде отсутствуют проверки условий ошибок. Убедитесь, что объект фактически является объектом перед вызовом его методов.
Пример типичного будет
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
В приведенном выше примере запрос не может и prepare()
назначит false
на $statement
. Попытка вызвать метод execute()
приведет к Fatal Error, потому что false
является «не объектом», потому что значение является логическим.
Выясните , почему ваша функция вернула логическое значение вместо объекта. Например, проверьте объект $pdo
для последней произошедшей ошибки. Подробности о том, как отлаживать это, будут зависеть от того, как обрабатываются ошибки для конкретной рассматриваемой функции / объекта / класса.
Если даже сбой ->prepare
не выполняется, то ваш дескриптор
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
базы данных
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
не попал в текущий объем . Найдите, где он определился. Затем передайте его как параметр, сохраните его как свойство или поделите его через глобальную область.
Другой проблемой может быть условное создание объекта, а затем попытка вызова метода вне этого условного блока. Например,
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
Пытаясь выполнить метод вне условного блока, ваш объект не может быть определен.
Вопросы, относящиеся:
Это - классический основанный на состоянии тест по сравнению с основанным на поведении сценарием тестирования.
В этом смехотворно простом примере, тестирующем вывод, прекрасен. В какой-то момент, хотя, Вы столкнетесь с тестами, где, осматривая состояние после того, как выполнение является сложным. Вместо этого Вы хотите проверить поведение (например, проверить, что changeit назвали с определенным значением).
В той точке, вероятно, необходимо изучить платформу фиктивного объекта как Носорог. Насмешки (.Net) или Mockito (Java) и начинают писать больше основанного на интерфейсе кода.
У Вас есть много опций. То, какой является лучшим, зависит от деталей, которые не ясны из Вашего вопроса.
modify
так же, как если бы это был несвязанный метод. Преимущество: это могло бы в какой-то момент стать тем. replaceit
и changeit
просто самая простая реализация, которая могла возможно работать . Если Ваш практикуют TDD, это должно прибыть естественно к Вам. Преимущество: высокое тестовое покрытие без очень дублированного усилия. replaceit
и changeit
с консервированными ответами или так, чтобы они установили распознающиеся переменные (переменные, которые указывают, назвали ли метод с правильным значением (значениями)). Преимущество: мог бы возможно упростить Ваши тесты (или не), иногда даже просто сделайте тестирование возможным. replaceit
и changeit
методы, включая интерфейс для того класса. Тупик или Насмешка, которые взаимодействуют через интерфейс при тестировании modify
. Преимущество: мог бы и сделать Ваш дизайн больше тестируемый и лучше разъединенный/допускающий повторное использование в целом (или не). Просто тест modify
.
Modify
, как предполагается, возвращает определенные значения, когда дали определенные значения.
Это неважно , как изменяют, делает его задание - только, что это делает его задание.
И если в будущем Вы изменяетесь modify
для использования различных методов (или никаких методов), оно не делает, и не должен, и не быть, влиять тесты.
Однако также протестируйте replaceit' and
changeit'.
Если Вы уже протестировали replaceit()
и changeit()
независимо, то единственная вещь, которую Вы оставили тесту, если условие. Тест modify()
с несколькими значениями для проверки это вызывает правильную функцию при правильных условиях (те условия, являющиеся null
и Strings
из длины 4, 5, и 6 для примера кода, который Вы дали).
В порядке предпочтения
.
public TestModifyIfValueLength..()
{
string expectedValue = .. ;// literal result of replaceit(value)
Assert.Equals( expectedValue, modify("asd") );
}
Предположения
Каков "тестовый код" в этом случае? Установка и проверка результатов? Если так, я осуществил бы рефакторинг его в различный метод и использовал бы его от каждого из тестов. Я только сделал бы это, если существует sigificant сумма его хотя - существует преимущество удобочитаемости для способности видеть все, что тест делает, только путем чтения кода того метода.
Сложные методы тестирования часто беспокоят меня для начала, чтобы быть честными - часто их нельзя реалистично избежать, но если Вы можете упрощать их, это стоит сделать так.
Ну, нет, Ваш тестовый код не будет 99% то же, потому что Вы на самом деле тестируете что-то другое здесь, если replaceit, changeit и не изменяют весь возврат те же значения.
Не уверенный, почему трудность. Тест для изменить метода должен быть приблизительно четырьмя строками долго. Так как Вы уже тестируете базовую функциональность и все, что Вы хотите сделать, удостоверяются, что этот конкретный метод не повреждается, пишущий тест, который тестирует два возможных пути выполнения кода в этом функциональном возврате, математические ожидания должны быть достаточными.
Если бы Вы уже записали тесты для replaceit () и changeit (), тест для изменяет, просто проверил бы, что различные результаты возвращаются в зависимости от значения 'значения'. Однако Вы будете просто повторно реализовывать логику метода в тесте, который немного абсурден.
В этом случае я не протестировал бы, изменяют, пока это не имеет более сложную логику, или лучше - используется другим методом, который является более значительным протестировать.
Вам в основном нужны 2 теста.
1) Передача в строке как "Быстрые Переходы Brown Fox!" (длина, больше, чем пять), удостоверяется, что значение затронуто replaceit(...)
2) Передача в строке как "Нечто" (длина - меньше чем пять), и удостоверьтесь, что значение затронуто changeit(...)
, Ваш тест (в псевдо коде) мог бы быть похожим на это:
testLongValue() {
string testValue = "A value longer than 5 chars";
string expected = "Replaced!";
string actual = modify(testValue);
assertEqual(expected, actual);
}
testShortValue() {
string testValue = "len4";
string expected = "Changed!";
string actual = modify(testValue);
assertEqual(expected, actual);
}
, Очевидно, я мог дать Вам более реалистический пример, если бы я знал то, что replacit () и changeit (), как предполагалось, сделали, но это должно дать Вам идею. Если это видоизменяет ссылку исходного значения вместо того, чтобы возвратить его, можно просто использовать testValue в качестве фактического значения после того, как вызов происходит.
При тестировании граничных условий как if (value.length > 5)
необходимо удостовериться, что данные тестирования содержат значения value
, которые имеют длину 4
, 5
, или 6
.
То же как Justin Standard, плюс передача null
как значение (который, очевидно, будет сбои для фрагмента кода, который Вы даете нам;)) Основное правило для Поблочного тестирования является "тестом только, что характерно для метода под тестом". И это вполне... редкий для имения метода, который не называет другой.