#laravel #mocking #phpunit #php-pest
Вопрос:
В моем приложении у меня есть служба, которая использует функцию, связанную с моделью.
Эта функция уже была протестирована (в ее модульном тесте), и в моем функциональном тесте мне просто нужно «использовать» ее выходное значение.
Поскольку эта функция «сложная», я бы высмеял ее значение, не беспокоясь о том, что делает функция. Таков сценарий:
Модель
class MyModel { public function calculateSomething() { // Implementation, already unit tested // Here i put some "crazy" logic (this is not real :) ) if ($this-gt;field_a lt; 10 || $this-gt;field_b gt; 15) { return true; } if ($this-gt;field_c !== null || $this-gt;field_e lt; 50) { return false; } return true; } }
В моей службе мне не нужно воссоздавать эти условия, мне просто нужно сказать: «в этом тесте calculateSomething
будет возвращено значение true», не важно, почему оно возвращается истинным
Обслуживание
class MyService { public function myMethod($id) { $models = MyModel::all(); foreach($models as $model) { if ($model-gt;calculateSomething()) { // Do domething here } else { // Do other stuff here } } } public function myMethodIsolated($model) { if ($model-gt;calculateSomething()) { // Do domething here } else { // Do other stuff here } } }
Обычно я издеваюсь над сервисом, но я никогда не издеваюсь над функцией внутри модели, можно ли издеваться над функцией, вычисляющей что-то ?
В моем примере я предоставил изолированную версию функции, называемую myMethodIsolated, в которой я передаю один экземпляр.
Комментарии:
1. Не могли бы вы добавить больше информации о том, что
calculateSomething
бы вы сделали? Я думаю, что «что-то не так», что-то кажется неправильным. Вы никогда не должны издеваться над aModel
, так как это может скрыть/не запускать код, основанный на событиях или подобных… объясните подробнее, что делает этот метод, возможно, мы сможем инкапсулировать его еще больше.2. это
calculateSomething
функция, которая проста в модульном тестировании, потому что я могу создать все условия для ее тестирования. В тесте функций мне не нужно заново создавать эти условия, но мне просто нужно использовать его возвращаемое значение для проверки логики.3. Этот код не поддается проверке.
Model::all
вернет много экземпляров, и вы вызываете его в самой службе, что не дает вам возможности полностью или частично издеваться над ними. Лучшее, что вы можете сделать, — это использовать фабрику для обработки ваших данных таким образом, чтобы ваша функция возвращаласьtrue
, но это будет означать, что ваш код функции будет выполнен. В Laravel фабрики-это способ «имитировать» данные. Если вы все еще хотите издеваться над своими моделями, вам нужно будет изменить своюmyMethod
, чтобы использовать коллекцию моделей в качестве аргумента и издеваться над каждой моделью в своем тесте, прежде чем проходить его