实现构建器模式时无法模拟
Unable to mock while implementing builder pattern
我很难测试在逻辑中使用构建器模式 (BuilderClass) 的 class(TestClass)。我无法模拟生成器 class(BuilderClass)。以下是我的逻辑的简化版本。
public class TestClass {
public int methodA() {
ExternalDependency e = BuilerClass.builder().withName("xyz").withNumber(10).build();
return e.callExternalFunction();
}
}
这是我的建筑工人 class
public class BuilderClass {
public static BuilderClass builder() { return new BuilderClass(); }
int number;
String name;
public BuilderClass withName(String name) {
this.name = name;
return this;
}
public BuilderClass withNumber(int number) {
this.number = number;
return this;
}
public ExternalDependency build() {
return new ExternalDependency(name,number);
}
}
对于我的测试 class,我将 Mockito 与 Dataprovider 结合使用。
@RunWith(DataProviderRunner.class)
class TestClassTest {
@Mock private ExternalDependency e;
@Mock private BuilderClass b;
@InjectMocks private TestClass t;
@Before public void setUp() { MockitoAnnotations.initMocks(this); }
@Test public void testMethodA() {
when(b.withName(any(String.class)).thenReturn(b); //This is not mocking
when(b.withNumber(10)).thenReturn(b); //This is not mocking
Assert.notNull(this.t.methodA()); //Control while execution is going to implementation of withName and withNumber, which should not happen right.
}
如果我遗漏了什么,请帮助我。谢谢
}
类似于 kryger 在上面的评论中所说的,您可能需要像这样进行重构:
在您的 class 测试中,创建一个接缝以用模拟替换 e
:
public class TestClass {
public int methodA() {
ExternalDependency e = buildExternalDependency("xyz", 10);
return e.callExternalFunction();
}
protected ExternalDependency buildExternalDependency(String name, int number) {
return BuilerClass.builder().withName(name).withNumber(number).build();
}
}
在测试代码中,覆盖测试 class 以用模拟替换 e
并验证对构建器的输入:
@RunWith(DataProviderRunner.class)
class TestClassTest {
@Mock private ExternalDependency e;
private TestClass t;
@Before public void setUp() {
MockitoAnnotations.initMocks(this);
t = new TestClass() {
@Override
protected ExternalDependency buildExternalDependency(String name, int number) {
// validate inputs:
Assert.assertEquals(10, number);
Assert.assertEquals("xyz", name);
return e; // provide the mock
}
}
}
@Test public void testMethodA() {
// TODO: mock behavior of callExternalFunction() here
Assert.notNull(this.t.methodA());
}
}
您可能希望通过重构进一步将 buildExternalDependency() 移动到另一个 class 中,它可以被模拟并注入到 TestClass 的构造函数中。
我很难测试在逻辑中使用构建器模式 (BuilderClass) 的 class(TestClass)。我无法模拟生成器 class(BuilderClass)。以下是我的逻辑的简化版本。
public class TestClass {
public int methodA() {
ExternalDependency e = BuilerClass.builder().withName("xyz").withNumber(10).build();
return e.callExternalFunction();
}
}
这是我的建筑工人 class
public class BuilderClass {
public static BuilderClass builder() { return new BuilderClass(); }
int number;
String name;
public BuilderClass withName(String name) {
this.name = name;
return this;
}
public BuilderClass withNumber(int number) {
this.number = number;
return this;
}
public ExternalDependency build() {
return new ExternalDependency(name,number);
}
}
对于我的测试 class,我将 Mockito 与 Dataprovider 结合使用。
@RunWith(DataProviderRunner.class)
class TestClassTest {
@Mock private ExternalDependency e;
@Mock private BuilderClass b;
@InjectMocks private TestClass t;
@Before public void setUp() { MockitoAnnotations.initMocks(this); }
@Test public void testMethodA() {
when(b.withName(any(String.class)).thenReturn(b); //This is not mocking
when(b.withNumber(10)).thenReturn(b); //This is not mocking
Assert.notNull(this.t.methodA()); //Control while execution is going to implementation of withName and withNumber, which should not happen right.
}
如果我遗漏了什么,请帮助我。谢谢 }
类似于 kryger 在上面的评论中所说的,您可能需要像这样进行重构:
在您的 class 测试中,创建一个接缝以用模拟替换 e
:
public class TestClass {
public int methodA() {
ExternalDependency e = buildExternalDependency("xyz", 10);
return e.callExternalFunction();
}
protected ExternalDependency buildExternalDependency(String name, int number) {
return BuilerClass.builder().withName(name).withNumber(number).build();
}
}
在测试代码中,覆盖测试 class 以用模拟替换 e
并验证对构建器的输入:
@RunWith(DataProviderRunner.class)
class TestClassTest {
@Mock private ExternalDependency e;
private TestClass t;
@Before public void setUp() {
MockitoAnnotations.initMocks(this);
t = new TestClass() {
@Override
protected ExternalDependency buildExternalDependency(String name, int number) {
// validate inputs:
Assert.assertEquals(10, number);
Assert.assertEquals("xyz", name);
return e; // provide the mock
}
}
}
@Test public void testMethodA() {
// TODO: mock behavior of callExternalFunction() here
Assert.notNull(this.t.methodA());
}
}
您可能希望通过重构进一步将 buildExternalDependency() 移动到另一个 class 中,它可以被模拟并注入到 TestClass 的构造函数中。