Как смоделировать пустой метод с помощью Functional Interface / lambda param? - PullRequest
1 голос
/ 31 октября 2019

Как мне смоделировать лямбда-выражение, которое передается в качестве параметра в вызов метода void?

У меня есть следующая структура класса, которую мне нужно проверить, но я не могу даже создать ее экземпляр из-заэто конструктор

Есть ли способ смоделировать вызов метода someManager.doSomething? Или способ издеваться над item.isDoItemSave?

Я не могу понять это, и SomeClass.setDoSave выбрасывает нулевой указатель на обратный вызов (SomeClass line 18), поскольку doSave является нулем.

Класс, который я хочу создать:

public SomeClass() {

    private Boolean doSave;
    private SomeManager someManager;
    private SaveAction action;    

    public SomeClass(SomeManager someManager) {
        this.someManager = someManager;
        action = setDoSave() ? SAVE : null;
    } 

    private boolean setDoSave() {
        if(doSave == null) {
            someManager.doSomething(item -> {
                doSave = item.isDoItemSave();
            });
        }
        return doSave;
    }

}

SomeManager.doSomething void:

public void doSomething(ItemUpdate update){
   Item item = new Item();
   update.update(item);
}

ItemUpdate - это функциональный интерфейс:

@FunctionalInterface
public interface ItemUpdate {
    void update(Item item);
}

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

Мой тестовый класс выглядит следующим образом, естественно, тесты не выполняются при вызове конструктора @BeforeEach on SomeClass:

class SomeClassTest {

    private SomeClass someClass;

    @Mock
    private SomeManager someManagerMock;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
        this.someClass = new SomeClass(someManagerMock);
    }

    @Test
    void someClassTest() {
        someClass.anyOtherMethod();
    }

}

Ответы [ 3 ]

1 голос
/ 31 октября 2019

На данный момент я внес изменения, так что SomeClass как минимум создает экземпляры. Извлеченный урок, следите за вашими заданиями от Boolean до Boolean.

    private boolean setDoSave() {
        if(doSave == null) {
            someManager.doSomething(item -> {
                doSave = item.isDoItemSave();
            });
        }

        return doSave != null ? doSave : false;
    }

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

1 голос
/ 31 октября 2019

Быстрый взгляд на документацию показывает следующий пример, который я применил к вашей ситуации

@BeforeEach
void setUp() {
    MockitoAnnotations.initMocks(this);

    //configure the mock
    // Java 8 - style 2 - assuming static import of AdditionalAnswers
    doAnswer(answerVoid(ItemUpdate update) -> {
        Item item = new Item();
        //...populate item as needed

        update.update(item);
    })
    .when(someManagerMock).doSomething(any(ItemUpdate.class));

    this.someClass = new SomeClass(someManagerMock);
}

Ссылка Поддержка пользовательских ответов Java 8

Обратите внимание, что яне проверял это. Я собираюсь основываться на том, что было показано в документах.

0 голосов
/ 31 октября 2019

Я не могу понять это, и SomeClass.setDoSave выбрасывает нулевой указатель, поскольку doSave имеет значение null.

SomeClass.setDoSave выдает NPE, поскольку переменная экземпляра someManager равна null.

Попробуйте добавить @RunWith(MockitoJUnitRunner.class) в свой тестовый класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...