我正在为一些遗留代码编写Junits,我意识到当我使用@Mock注解模拟我的依赖关系时,一些模拟的对象似乎有一个与之关联的mockito拦截器,而有些则没有。我缺乏计算机编程的基础知识,任何帮助都很感激。
//Did not work, because of lack of @InkectMocks,
//see that I create a new object of class to test.
public class foo {
ClassInTest classInTest;
AutoCloseable mocks;
@Mock
Animal animal;
@Mock
Bike vehicle;
@Before
public void init() {
mocks = openMocks(this);
classInTest = new ClassInTest();
}
@After
public void teardown() throws Exception {
mocks.close();
}
@Test
public void dogRidesBikeTest() {
classInTest.checkIfAnimalRidesVehicle(new Dog(), new Bike());
}
}
public interface Animal {
public String getName();
public String doSomething();
}
public class Dog implements Animal {
@Override
public String getName() {
return "Dog";
}
@Override
public String doSomething() {
return "Did something";
}
}
public interface Vehicle {
public String getName();
public String doSomething();
}
public class Bike implements Vehicle {
@Override
public String getName() {
return "Bike";
}
@Override
public String doSomething() {
return "Did something";
}
}
public class ClassInTest {
public boolean checkIfAnimalRidesVehicle(Animal animal, Vehicle vehicle) {
vehicle.doSomething();
remoteMagic(animal, vehicle);
return false;//dogs don't ride bikes!
}
public void remoteMagic(Animal animal, Vehicle vehicle) {
//magic magic magic
}
}
//This is an example of code that works,
//in line with @Lesiak's answer, the lack of a $MockitoMock$
//definition on a mock object should not stop you from being able
//to stub methods/interact with that mock in any way.
public class FooBarTest {
@InjectMocks
FooBar fooBar;
@Mock
List<String> mockList;
@Mock
CosmosAsyncContainer mockAsyncContainer;
@Mock
CosmosContainerResponse mockCosmosContainerResponse;
AutoCloseable autoCloseable;
@Before
public void setup() {
autoCloseable = openMocks(this);
}
@After
public void tearDown() throws Exception {
autoCloseable.close();
}
@Test
public void test() {
Mono<CosmosContainerResponse> raft = Mono.just(mockCosmosContainerResponse);
when(mockList.size()).thenReturn(3);
when(mockAsyncContainer.read()).thenReturn(raft);
var result = fooBar.helloWorld();
verify(mockList).size();
verify(mockAsyncContainer).read();
assertEquals(result, raft);
}
}
public class FooBar {
List<String> goodList;
CosmosAsyncContainer goodContainer;
public Mono<CosmosContainerResponse> helloWorld() {
assertEquals(3, goodList.size());
Mono<CosmosContainerResponse> raft;
try {
raft = goodContainer.read();
} catch (Exception ex) {
raft = Mono.empty();
System.out.println("gotcha!!");
}
return raft;
}
}
型
我用mockSomething(这是一个有一个与之关联的拦截器的接口)模拟一个接口,用mockSomethingElse(这是一个没有与之关联的拦截器的类)对象模拟一个类,这两者的区别是什么?
当我在测试“dogRidesBikeTest”上放置一个调试点并观察到目前为止在测试上下文中创建的对象时,我观察到其中一个对象上有一个mockito拦截器,而另一个没有。
如果没有拦截器会影响方法存根(我希望它会),如果是的话,我如何解决这个问题。
- 编辑:*
1.修复了在新代码示例中无法在我的模拟上存根方法的错误/原因。
1.最初的问题“为什么在一些mock对象上没有mockito拦截器”已经由@Lesiak回答
1.在任何mock对象上缺少$MockitoMock$指定应该不会干扰您与mock交互的方式,前提是您正确设置了测试/mock。
1条答案
按热度按时间xxb16uws1#
您正在使用mockito-inline,它会更改构造mock的方式:
这个替代的mock maker使用Java instrumentation API和子类化的组合,而不是创建一个新的类来表示mock。
InlineByteBuddyMockMaker javadoc说道:
这个mock maker在创建mock时会尽最大努力避免创建子类。否则,它将使用
org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker
创建mock类。这意味着以下条件为真字符串
除非满足以下条件中的任何一个,否则在这种情况下,mock生成器返回到子类的创建。
在代码中:
这两个模拟都是功能齐全的(stubbing工作等),但可以检测到差异,正如您已经注意到的那样。
另外,请注意,您没有将模拟传递给测试中的类--这是内部的吗?