java test - Инъекция @Полученное личное поле во время тестирования




3 Answers

Вы можете абсолютно вводить макеты в MyLauncher в свой тест. Я уверен, что если вы покажете, какую издевательскую структуру вы используете, кто-то быстро даст ответ. С mockito я бы рассмотрел использование @RunWith (MockitoJUnitRunner.class) и использование аннотаций для myLauncher. Он будет выглядеть примерно так, как показано ниже.

@RunWith(MockitoJUnitRunner.class)
public class MyLauncherTest
    @InjectMocks
    private MyLauncher myLauncher = new MyLauncher();

    @Mock
    private MyService myService;

    @Test
    public void someTest() {

    }
}
scanner junit

У меня есть компонентная установка, которая по сути является программой запуска приложения. Он настроен так:

@Component
public class MyLauncher {
    @Autowired
    MyService myService;

    //other methods
}

MyService аннотируется аннотацией @Service Spring и автоматически отключается в моем классе запуска без каких-либо проблем.

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

public class MyLauncherTest
    private MyLauncher myLauncher = new MyLauncher();

    @Test
    public void someTest() {

    }
}

Могу ли я создать объект Mock для MyService и ввести его в myLauncher в своем тестовом классе? У меня в настоящее время нет геттера или сеттера в myLauncher, так как Spring обрабатывает автоустановку. Если возможно, я бы не хотел добавлять геттеры и сеттеры. Могу ли я сообщить тестовому примеру, чтобы ввести объект-макет в переменную с использованием метода @Before init?

Если я собираюсь сделать это совершенно неправильно, не стесняйтесь это говорить. Я все еще новичок в этом. Моя главная цель - просто иметь некоторый Java-код или аннотацию, которая помещает макет в эту переменную @Autowired без необходимости писать метод setter или использовать файл applicationContext-test.xml. Я бы предпочел сохранить все для тестовых случаев в .java-файле вместо того, чтобы поддерживать отдельный applicationContent только для моих тестов.

Я надеюсь использовать Mockito для фальшивых объектов. Раньше я делал это, используя org.mockito.Mockito и создавая свои объекты с помощью Mockito.mock(MyClass.class)

Большое спасибо.




Иногда вы можете реорганизовать свой @Component для использования инъекции на основе конструктора или сеттера, чтобы настроить @Autowired (вы можете и все еще полагаться на @Autowired ). Теперь вы можете полностью создать свой тест без издевательских фреймворков, заменив тестовые заглушки (например, MailServiceStub Мартина Фоулера):

@Component
public class MyLauncher {

    private MyService myService;

    @Autowired
    MyLauncher(MyService myService) {
        this.myService = myService;
    }

    // other methods
}

public class MyServiceStub implements MyService {
    // ...
}

public class MyLauncherTest
    private MyLauncher myLauncher;
    private MyServiceStub myServiceStub;

    @Before
    public void setUp() {
        myServiceStub = new MyServiceStub();
        myLauncher = new MyLauncher(myServiceStub);
    }

    @Test
    public void someTest() {

    }
}

Этот метод особенно полезен, если тест и тестируемый класс находятся в одном пакете, потому что тогда вы можете использовать модификатор доступа к package-private доступу по умолчанию, чтобы другие классы не обращались к нему. Обратите внимание, что вы все равно можете иметь свой производственный код в src/main/java но ваши тесты в каталогах src/main/test .

Если вам нравится Mockito, тогда вы по достоинству оцените MockitoJUnitRunner . Это позволяет вам делать «магические» вещи, такие как @Manuel показал вам:

@RunWith(MockitoJUnitRunner.class)
public class MyLauncherTest
    @InjectMocks
    private MyLauncher myLauncher; // no need to call the constructor

    @Mock
    private MyService myService;

    @Test
    public void someTest() {

    }
}

Кроме того, вы можете использовать бегун JUnit по умолчанию и вызывать MockitoAnnotations.initMocks() в setUp() чтобы Mockito инициализировал аннотированные значения. Вы можете найти дополнительную информацию в javadoc @InitMocks и в сообщении в блоге, которое я написал.




Я новый пользователь для Spring. Я нашел другое решение для этого. Использование рефлексии и создание общедоступных полей и назначение макетных объектов.

Это мой авторизационный контроллер, и у него есть некоторые личные свойства Autwired.

@RestController
public class AuthController {

    @Autowired
    private UsersDAOInterface usersDao;

    @Autowired
    private TokensDAOInterface tokensDao;

    @RequestMapping(path = "/auth/getToken", method = RequestMethod.POST)
    public @ResponseBody Object getToken(@RequestParam String username,
            @RequestParam String password) {
        User user = usersDao.getLoginUser(username, password);

        if (user == null)
            return new ErrorResult("Kullanıcıadı veya şifre hatalı");

        Token token = new Token();
        token.setTokenId("aergaerg");
        token.setUserId(1);
        token.setInsertDatetime(new Date());
        return token;
    }
}

И это мой тест Junit для AuthController. Я делаю публичные необходимые частные свойства и присваиваю им макетные объекты и рок :)

public class AuthControllerTest {

    @Test
    public void getToken() {
        try {
            UsersDAO mockUsersDao = mock(UsersDAO.class);
            TokensDAO mockTokensDao = mock(TokensDAO.class);

            User dummyUser = new User();
            dummyUser.setId(10);
            dummyUser.setUsername("nixarsoft");
            dummyUser.setTopId(0);

            when(mockUsersDao.getLoginUser(Matchers.anyString(), Matchers.anyString())) //
                    .thenReturn(dummyUser);

            AuthController ctrl = new AuthController();

            Field usersDaoField = ctrl.getClass().getDeclaredField("usersDao");
            usersDaoField.setAccessible(true);
            usersDaoField.set(ctrl, mockUsersDao);

            Field tokensDaoField = ctrl.getClass().getDeclaredField("tokensDao");
            tokensDaoField.setAccessible(true);
            tokensDaoField.set(ctrl, mockTokensDao);

            Token t = (Token) ctrl.getToken("test", "aergaeg");

            Assert.assertNotNull(t);

        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

}

Я не знаю преимуществ и недостатков, но это работает. У этой техники есть немного больше кода, но эти коды могут быть разделены различными методами и т. Д. Есть более хорошие ответы на этот вопрос, но я хочу указать на другое решение. Извините за мой плохой английский. Имейте хороший java для всех :)




Related

java spring unit-testing junit autowired