我对Mockito很新,在清理方面遇到了一些麻烦.
我曾经使用JMock2进行单元测试.据我所知,JMock2在上下文中保留了期望和其他模拟信息,这些信息将针对每种测试方法进行重建.因此,每种测试方法都不会受到其他测试方法的干扰.
我在使用JMock2时采用了相同的弹簧测试策略,我发现我在帖子中使用的策略存在潜在问题:应用程序上下文是针对每个测试方法重建的,因此减慢了整个测试过程.
我注意到许多文章建议在春季测试中使用Mockito,我想尝试一下.它运行良好,直到我在测试用例中编写两个测试方法.每个测试方法在单独运行时通过,其中一个如果一起运行则失败.我推测这是因为模拟信息保存在模拟本身中(因为我没有在JMock中看到任何类似的上下文对象)并且模拟(和应用程序上下文)在两个测试方法中共享.
我通过在@Before方法中添加reset()来解决它.我的问题是处理这种情况的最佳做法是什么(reset()的javadoc说如果你需要reset(),代码就闻到了?)?任何想法都是欣赏,提前谢谢.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/booking-servlet.xml",
"classpath:test-booking-servlet.xml" })
@WebAppConfiguration
public class PlaceOrderControllerIntegrationTests implements IntegrationTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Autowired
private PlaceOrderService placeOrderService;
@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
reset(placeOrderService);// reset mock
}
@Test
public void fowardsToFoodSelectionViewAfterPendingOrderIsPlaced()
throws Exception {
final Address deliveryAddress = new AddressFixture().build();
final String deliveryTime = twoHoursLater();
final PendingOrder pendingOrder = new PendingOrderFixture()
.with(deliveryAddress).at(with(deliveryTime)).build();
when(placeOrderService.placeOrder(deliveryAddress, with(deliveryTime)))
.thenReturn(pendingOrder);
mockMvc.perform(...);
}
@Test
public void returnsToPlaceOrderViewWhenFailsToPlaceOrder() throws Exception …Run Code Online (Sandbox Code Playgroud) 如果我使用Wrapper类类型变量作为参数Mockito测试用例正在通过但是,如何为int基本类型变量编写Mockito测试用例,这是ServiceImpl中方法的参数.
我已经开始发现Mockito图书馆了,有一个问题,我找不到合适的答案.
如果我在UserDAO类中有这样的方法,可以将用户保存在数据库中:
public class UserDAO{
...
public void create(User user) {
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet generatedKeys = null;
try {
connection = getConnection();
pstmt = connection.prepareStatement(INSERT_USER,
PreparedStatement.RETURN_GENERATED_KEYS);
int counter = 1;
pstmt.setString(counter++, user.getFirstName());
pstmt.setString(counter++, user.getLastName());
pstmt.setString(counter++, user.getEmail());
pstmt.setString(counter++, user.getPassword());
pstmt.setString(counter++, user.getRole());
pstmt.setString(counter, user.getLang());
pstmt.execute();
connection.commit();
generatedKeys = pstmt.getGeneratedKeys();
if (generatedKeys.next()) {
user.setId(generatedKeys.getInt(Fields.GENERATED_KEY));
}
} catch (SQLException e) {
rollback(connection);
LOG.error("Can not create a user", e);
} finally {
close(connection);
close(pstmt);
close(generatedKeys);
}
}
....
} …Run Code Online (Sandbox Code Playgroud) 我需要测试一些遗留代码,它在方法调用中使用单例.测试的目的是确保clas sunder测试调用单例方法.我在SO上看到过类似的问题,但是所有的答案都需要其他依赖项(不同的测试框架) - 我很遗憾只能使用Mockito和JUnit,但这种流行的框架应该是完全可能的.
单身人士:
public class FormatterService {
private static FormatterService INSTANCE;
private FormatterService() {
}
public static FormatterService getInstance() {
if (INSTANCE == null) {
INSTANCE = new FormatterService();
}
return INSTANCE;
}
public String formatTachoIcon() {
return "URL";
}
}
Run Code Online (Sandbox Code Playgroud)
被测试的课程:
public class DriverSnapshotHandler {
public String getImageURL() {
return FormatterService.getInstance().formatTachoIcon();
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试:
public class TestDriverSnapshotHandler {
private FormatterService formatter;
@Before
public void setUp() {
formatter = mock(FormatterService.class);
when(FormatterService.getInstance()).thenReturn(formatter);
when(formatter.formatTachoIcon()).thenReturn("MockedURL");
}
@Test
public void testFormatterServiceIsCalled() { …Run Code Online (Sandbox Code Playgroud) 我是Java单元测试的新手,我听说Mockito框架非常适合测试目的.
我开发了一个REST服务器(CRUD方法),现在我想测试它,但我不知道怎么做?
更多我不知道这个测试程序应该如何开始.我的服务器应该在localhost上工作,然后在该url上调用(例如localhost:8888)?
这是我到目前为止所尝试的,但我很确定这不是正确的方法.
@Test
public void testInitialize() {
RESTfulGeneric rest = mock(RESTfulGeneric.class);
ResponseBuilder builder = Response.status(Response.Status.OK);
builder = Response.status(Response.Status.OK).entity(
"Your schema was succesfully created!");
when(rest.initialize(DatabaseSchema)).thenReturn(builder.build());
String result = rest.initialize(DatabaseSchema).getEntity().toString();
System.out.println("Here: " + result);
assertEquals("Your schema was succesfully created!", result);
}
Run Code Online (Sandbox Code Playgroud)
这是initialize方法的代码.
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/initialize")
public Response initialize(String DatabaseSchema) {
/** Set the LogLevel to Info, severe, warning and info will be written */
LOGGER.setLevel(Level.INFO);
ResponseBuilder builder = Response.status(Response.Status.OK);
LOGGER.info("POST/initialize - Initialize the " + user.getUserEmail()
+ " …Run Code Online (Sandbox Code Playgroud) 我正在使用mockito.我想RuntimeException在调用unmocked方法时抛出.有没有办法做到这一点?
要检查与模拟的交互次数,其中方法调用中的参数是某种类型,可以做
mock.someMethod(new FirstClass());
mock.someMethod(new OtherClass());
verify(mock, times(1)).someMethod(isA(FirstClass.class));
Run Code Online (Sandbox Code Playgroud)
这将通过感谢调用isA自从someMethod被调用两次,但只有一次与参数FirstClass
但是,使用ArgumentCaptor时,这种模式似乎是不可能的,即使Captor是为特定参数创建的 FirstClass
这不起作用
mock.someMethod(new FirstClass());
mock.someMethod(new OtherClass());
ArgumentCaptor<FirstClass> captor = ArgumentCaptor.forClass(FirstClass.class);
verify(mock, times(1)).someMethod(captor.capture());
Run Code Online (Sandbox Code Playgroud)
它说模拟不止一次被召唤.
在获取进一步检查的参数时,有没有办法完成此验证?
我试图使用Mockito测试一些遗留代码,并且该方法是void类型.
我已经在其他类中省略了很多对方法的调用,这很好用.但是,我还需要能够在同一个类中删除对其他方法的某些调用.
目前这不起作用.
例如,我的班级如下:
public class Test {
public Test(dummy dummy) {
}
public void checkTask(Task task, List <String> dependencyOnLastSuccessList) throws TaskException {
callToOtherClass.method1 // This works fine, I can stub it using mockito
updateAndReschedule(Long id, String message) // call to method in same class, I cannot stub it
}
public void updateAndReschedule(Long id, String message) {
//method logic.....
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的testClass显示我现在的情况:
@Test
public void testMyMethod() {
Test testRef = new Test(taskJob);
Test spy = spy (testRef);
// when a …Run Code Online (Sandbox Code Playgroud) 我有一个@Controller带有这个构造函数的Spring MVC :
@Autowired
public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/}
Run Code Online (Sandbox Code Playgroud)
我想为这个Controller编写一个独立的单元测试:
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
private String myProperty = "my property value";
@InjectMocks
private AbcController controllerUnderTest;
/* tests */
}
Run Code Online (Sandbox Code Playgroud)
有没有办法@InjectMocks注入我的String属性?我知道我不能模拟一个字符串,因为它是不可变的,但我可以在这里注入一个普通的字符串吗?
@InjectMocks在这种情况下,默认情况下会注入null.@Mock如果我戴上它,可以理解地抛出异常myProperty.是否有另外一个注释我错过了只是意味着"注入这个确切的对象而不是它的模拟"?
我正在使用mockito来测试我的业务服务,它使用了我想要模拟的实用程序.对于具有不同参数的实用程序,每个服务方法至少有2-3个调用.
有没有推荐的方法来使用多个when(...).thenReturn(...)相同的方法但不同的参数?
我也想在any()里面使用游行者.可能吗?
更新:示例代码.
@Test
public void myTest() {
when(service.foo(any(), new ARequest(1, "A"))).thenReturn(new AResponse(1, "passed"));
when(service.foo(any(), new ARequest(2, "2A"))).thenReturn(new AResponse(2, "passed"));
when(service.foo(any(), new BRequest(1, "B"))).thenReturn(new BResponse(112, "passed"));
c.execute();
}
public class ClassUnderTest {
Service service = new Service();
public void execute() {
AResponse ar = (AResponse) service.foo("A1", new ARequest(1, "A"));
AResponse ar2 = (AResponse) service.foo("A2", new ARequest(2, "2A"));
BResponse br = (BResponse) service.foo("B1", new BRequest(1, "B"));
}
}
public class Service {
public Object foo(String firstArgument, …Run Code Online (Sandbox Code Playgroud) mockito ×10
java ×9
unit-testing ×6
junit ×3
mocking ×2
dao ×1
rest ×1
spring ×1
spring-mvc ×1
spring-test ×1