Пользователь пока ничего не рассказал о себе

Наибольший вклад в теги

Все теги (5)

Лучшие ответы пользователя

Все ответы (9)
  • Как протестировать сервлет?

    @ads83
    Проблема в том, что твой сервлет создает каждый раз новый dbManager. Ему пофигу, что ты там мокаешь - он создает. каждый вызов. new DBManagerService()
    Это ужас-ужас и за такое бьют линейкой по пальцам в реальном коде недопустимо

    Стандартное решение - создать поле в классе и использовать code injection, т.е. прописать аннотацию @Autowired:
    public class ConformPay extends HttpServlet {
      private static final Logger LOGGER = Logger.getLogger(ConformPay.class);
      private static final long serialVersionUID = 1L;
    
    @Autowired
    DBManager dbManager


    Потом тебе надо указать Спрингу (или аналогу), где взять компонент DBManager.
    В тесте ты указываешь, что вместо настоящего DBManager нужно использовать mock.
    ----
    Другой вариант, менее трудоемкий, но и менее распространенный - это использовать мок на геттере. Так же создаешь в сервлете поле, создаешь/инжектируешь его в конструкторе и создаешь методDBManager getDBManager() {return dBManager);}. Потом в методе `doPost` обращаешься не к полю dBManager, а дергаешь геттер: getDBManager().delPayment(dtime);
    В тесте же на своем сервлете ставишь заглушку на этот метод:
    when(conformPay.getDBManager()).thenReturn(dbManagerMock)

    Проблема в этом подходе в том, что тебе нужно не создавать заглушку для conformPay, а использовать настоящий класс с заглушкой. Почитай про метод spy(), а также почему его рекомендуют применять только в исключительных случаях.
    Ответ написан
    Комментировать
  • Как построить архитектуру @Service с Spring и MongoRepository?

    @ads83
    @Service - это класс. Он может иметь много методов, и каждый контроллер будет вызывать нужный. В каждом будет делаться своя, уникальная часть, а сохраниен пойдет через общий метод. Например

    // В Андроид контроллере
    service.processAndroidLink(link)
    // В iOS контроллере
    service.processMacLink(link)
    
    // в самом сервисе будут такие методы:
    public void processAndroidLink(URL link) {
      // подготавливаем данные для записи
      URL androidLink = link;
      URL iosLink = createIosLink(link);
      URL webLink = createWebLink(link);
      var doc = prepareDocument(andriodLink, iosLink, webLink);
      save(doc);
    }
    public void processWebLink(URL link) {
      // подготавливаем данные для записи
      URL androidLink = createAndroidLink(link);
      URL iosLink = createIosLink(link);
      URL webLink = link;
      var doc = prepareDocument(andriodLink, iosLink, webLink);
      save(doc);
    }
    private void save(document) {сохраняем в MongoDB}
    }

    Понятно, что вместо URL может быть любой другой тип.

    Обрати внимание, что метод сохранения разделен с prepareDocument: так проще тестировать, у них разные области видимости и в будущем prepareDocument может быть использован кем-то еще.

    В данном случае я намеренно обошел стороной вопрос проверки существования ссылки. Возможно, ты захочешь сделать это отдельным процессом. Возможно, встроишь в processAndroidLink.
    Ответ написан
    Комментировать
  • Как правильно заполнить многомеремный массив?

    @ads83
    В двумерном массиве "Х" - это две большие диагонали. Их заполнить можно без вложенных циклов:

    public void fillX(String[][] array) {
      for (int i=1; i<size; i++) {
        array[i][i] = "x" // главная диагональ
        array[i][size-i] = "x" // побочная диагональ
      }
    }

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

    С выводом все просто: используем во вложенном цикле print, чтобы не было перехода на новую строку, и println без параметров для начала новой строки во внешнем цикле.
    Я намеренно не пишу код, а описываю его словами, чтобы у тебя была возможность написать самому и потренироваться.
    Ответ написан
    Комментировать
  • Как приклеить строку к правому краю?

    @ads83
    При таком подходе - никак. Дело в том, что у вас текст формируется один раз, а ширина "экрана" может меняться (телефон повернули, изменили размер окна).

    Чтобы использовать хоть какое-нибудь выравнивание, придется отказаться от многострочных текстов в одном элементе. Чаще всего делают вложенные друг в друга компоненты. Например, таблицу из двух колонок. В каждой строке слева текст, справа числа. Ширина правого столбца будет отвечать за отступ чисел от текста.

    Есть и другие варианты, но главное - код менять придется.
    Ответ написан
    Комментировать
  • Как строку перевести в математическое выражение?

    @ads83
    что делать со знаками я не знаю
    Нужно разбирать (парсить) все выражение целиком. Глобально, есть два варианта:
    1. Пойти легким путем и использовать готовые парсеры. Например, в ответе profesor08 используется встроенный в движок javascript - фунцкия eval. Она все делает сама: определяет числа, расставляет приоритет операций, считает.
    2. Пойти интересным путем и написать парсер самому. Такие задачи могут дать в конце семестра студентам профильного вуза. Парсер проходит по выражению и строит некое внутреннее представление. Потом проходит еще раз и вычисляет значение, исходя из этого представления. Чаще всего используется обратная польская нотация. Ничего сложного, но скорее всего, первый раз уйдет не один вечер чтобы написать и отладить.

    Ответ написан
    1 комментарий