在没有 setter 的情况下设置模拟字段 class
Set field of mock class without setter
我想用 spock 测试这个方法
public class MainService {
private final DLCRDDLPortType dlcrddlPortType;
public void startProcess(Application app) {
Holder<String> status = new Holder<>();
Holder<String> statusText = new Holder<>();
dlcrddlPortType.startProcess(app.getApplicationId(), status, statusText);
if (status.value.equals(FAIL_RESPONSE_STATUS)) {
throw new FailResponseException(String.format("Failed to get response with status %s and description %s", status.value, statusText.value));
}}
public final class Holder<T> implements Serializable {
public T value;
public Holder() {
}
public Holder(T value) {
this.value = value;
}
}
status.value 为 null,没有 setter 我无法更改它,我无法使用构造函数创建它,因为我需要模拟。我该如何解决?
错误:
无法调用“String.equals(Object)”,因为“status.value”为空
我的测试:
private DLCRDDLPortType dlcrddlPortType
private MainService mainService
private Holder status
private Holder statusText
void setup() {
status = GroovyMock()
dlcrddlPortType = Mock()
mainService= new MainService(dlcrddlPortType)
}
def "startProcess success"() {
given:
def appId = 171l
ReflectionTestUtils.setField(status, "value", "SUCCESS")
def app = Application.builder().applicationId(appId).build()
when:
mainService.startProcess(app)
then:
1 * dlcrddlPortType.startProcess(appId, status, statusText)
}
我试图根据您的部分示例创建一个 MCVE。
重要的部分是:
1 * dlcrddlPortType.startProcess(appId, _, _) >> { id, status, statusText ->
status.value = "SUCCESS"
}
有了这个,您可以使用响应生成器访问参数,并将值设置为状态持有者。
这里是稍微改编的例子:
public class MainService {
private DLCRDDLPortType dlcrddlPortType;
public void startProcess(Application app) {
Holder<String> status = new Holder<>();
Holder<String> statusText = new Holder<>();
dlcrddlPortType.startProcess(app.getApplicationId(), status, statusText);
if (status.value.equals("FAIL_RESPONSE_STATUS")) {
throw new IllegalStateException(String.format("Failed to get response with status %s and description %s", status.value, statusText.value));
}
}
}
class Application {
long applicationId
}
interface DLCRDDLPortType {
void startProcess(long applicationId, Holder<String> status, Holder<String> statusText)
}
public final class Holder<T> implements Serializable {
public T value;
public Holder() {
}
public Holder(T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
}
class ASpec extends Specification {
def "startProcess success"() {
given:
DLCRDDLPortType dlcrddlPortType = Mock()
MainService mainService = new MainService(dlcrddlPortType: dlcrddlPortType)
long appId = 171l
def app = new Application(applicationId: appId)
when:
mainService.startProcess(app)
then:
1 * dlcrddlPortType.startProcess(appId, _, _) >> { id, status, statusText ->
status.value = "SUCCESS"
}
}
}
试试
我想用 spock 测试这个方法
public class MainService {
private final DLCRDDLPortType dlcrddlPortType;
public void startProcess(Application app) {
Holder<String> status = new Holder<>();
Holder<String> statusText = new Holder<>();
dlcrddlPortType.startProcess(app.getApplicationId(), status, statusText);
if (status.value.equals(FAIL_RESPONSE_STATUS)) {
throw new FailResponseException(String.format("Failed to get response with status %s and description %s", status.value, statusText.value));
}}
public final class Holder<T> implements Serializable {
public T value;
public Holder() {
}
public Holder(T value) {
this.value = value;
}
}
status.value 为 null,没有 setter 我无法更改它,我无法使用构造函数创建它,因为我需要模拟。我该如何解决?
错误: 无法调用“String.equals(Object)”,因为“status.value”为空
我的测试:
private DLCRDDLPortType dlcrddlPortType
private MainService mainService
private Holder status
private Holder statusText
void setup() {
status = GroovyMock()
dlcrddlPortType = Mock()
mainService= new MainService(dlcrddlPortType)
}
def "startProcess success"() {
given:
def appId = 171l
ReflectionTestUtils.setField(status, "value", "SUCCESS")
def app = Application.builder().applicationId(appId).build()
when:
mainService.startProcess(app)
then:
1 * dlcrddlPortType.startProcess(appId, status, statusText)
}
我试图根据您的部分示例创建一个 MCVE。 重要的部分是:
1 * dlcrddlPortType.startProcess(appId, _, _) >> { id, status, statusText ->
status.value = "SUCCESS"
}
有了这个,您可以使用响应生成器访问参数,并将值设置为状态持有者。
这里是稍微改编的例子:
public class MainService {
private DLCRDDLPortType dlcrddlPortType;
public void startProcess(Application app) {
Holder<String> status = new Holder<>();
Holder<String> statusText = new Holder<>();
dlcrddlPortType.startProcess(app.getApplicationId(), status, statusText);
if (status.value.equals("FAIL_RESPONSE_STATUS")) {
throw new IllegalStateException(String.format("Failed to get response with status %s and description %s", status.value, statusText.value));
}
}
}
class Application {
long applicationId
}
interface DLCRDDLPortType {
void startProcess(long applicationId, Holder<String> status, Holder<String> statusText)
}
public final class Holder<T> implements Serializable {
public T value;
public Holder() {
}
public Holder(T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
}
class ASpec extends Specification {
def "startProcess success"() {
given:
DLCRDDLPortType dlcrddlPortType = Mock()
MainService mainService = new MainService(dlcrddlPortType: dlcrddlPortType)
long appId = 171l
def app = new Application(applicationId: appId)
when:
mainService.startProcess(app)
then:
1 * dlcrddlPortType.startProcess(appId, _, _) >> { id, status, statusText ->
status.value = "SUCCESS"
}
}
}
试试