Java 如何模拟在使用JMockit测试的方法中创建的本地对象

Java 如何模拟在使用JMockit测试的方法中创建的本地对象,java,junit,mocking,junit4,jmockit,Java,Junit,Mocking,Junit4,Jmockit,我无法模拟在我尝试测试的方法中创建的类的实例。下面是一个例子来说明这个问题 正在测试的类和方法: // class being used in the class to be tested public class SomeOtherClass{ public ResponseObject addObject(Request dtoObject){ /// Some business logic goes here return reponseObject; } }

我无法模拟在我尝试测试的方法中创建的类的实例。下面是一个例子来说明这个问题

正在测试的类和方法:

// class being used in the class to be tested
public class SomeOtherClass{

public ResponseObject addObject(Request dtoObject){
    /// Some business logic goes here

    return reponseObject;
  }
} 

// Class to be tested
public class ClassToBeTested {

public ClassToBeTested() {}

public void myMethodToBeTested() {
    SomeOtherClass otherClassObject = new SomeOtherClass();

    // Here I want mock the otherClassObject and also addObject method 
    // Eventhoug I mocked it seems to me that as otherClassObject is being created here locally 
    // I am unable to mock it.
    ReponseObject reponseObject = otherClassObject.addObject(dtoObject);

    // do some other stuff using the reponseObject
  }
}
public class TestClassToBeTested {
@Tested private ClassToBeTested classBeingTested;
@Injectable SomeOtherClass innerSomeOtherClass;

RequestObject myRequestObject = new RequestObject();
myRequestObject.setSomevalue1("1");
myRequestObject.setSomevalue2("2");

ResponseObject myMockResponseObject = new ResponseObject();
myMockResponseObject.setResultCode(SUCCESS);

@Test
public void shouldTestSomething() {
    new NonStrictExpectations(){{
        // Here I am returning the mocked response object.
        SomeOtherClass.addObject((SomeOtherClass)any);
        result =myMockResponseObject;
    }};   

    classBeingTested.myMethodToBeTested(); 

    // ... 
 }
}
// This is the class to be tested
public class MyMainClass {

public ResponseObject addItem(ProductList products) {

ResponseObject responseObject = new ResponseObject();

OtherService otherService = new OtherService();

List<Product> productList = new ArrayList<Product>();
productList = products.getProducts();

for (int i = 0; i < productList.size(); i++) {
  Product product = otherService.addProduct(productList.get(i));
  System.out.println("model.Product " + product.getName() + " added 
  successfully");
}

responseObject.setResponseCode("1");
responseObject.setResponseMessage("Success");
return responseObject;
 }
}

// Some other service internally used by MyMainClass
public class OtherService implements IService{
 public Product addProduct(Product product){

  // Some business logic to process the product
  System.out.println("Adding product :"+product.getName());

  return product;
  }
}

// Interface implemented by OtherService
public interface IService {

 Product addProduct(Product product);

}

// Sample ResponseObject class 
public class ResponseObject {

String responseCode;
String responseMessage;

public String getResponseMessage() {
   return responseMessage;
}

public void setResponseMessage(String responseMessage) {
   this.responseMessage = responseMessage;
}

public String getResponseCode() {
  return responseCode;
}

public void setResponseCode(String responseCode) {
  this.responseCode = responseCode;
}
}
public class MyMainClassTest {

@Tested
MyMainClass myMainClass;

@Mocked
IService otherService;

private List<Product> myProducts = new ArrayList<Product>();

@Before
public void init(){

  Product product1 = new Product();
  product1.setName("Test1");
  product1.setPid(1);
  product1.setPrice(100.00);
  myProducts.add(product1);
  Product product2 = new Product();
  product2.setName("Test2");
  product2.setPid(2);
  product2.setPrice(200.00);
  myProducts.add(product2);
}

@Test
public void addItem_Test() throws  Exception{
 myMainClass = new MyMainClass();

 new NonStrictExpectations(){{
  otherService.addProduct((Product)any);
  returns(myProducts.get(0));
 }};

 ProductList productList = new ProductList();
 productList.setProducts(myProducts);
 ResponseObject responseObject = myMainClass.addItem(productList);

 Assert.assertEquals(responseObject.getResponseMessage(),"Success");
}
}
测试类:

// class being used in the class to be tested
public class SomeOtherClass{

public ResponseObject addObject(Request dtoObject){
    /// Some business logic goes here

    return reponseObject;
  }
} 

// Class to be tested
public class ClassToBeTested {

public ClassToBeTested() {}

public void myMethodToBeTested() {
    SomeOtherClass otherClassObject = new SomeOtherClass();

    // Here I want mock the otherClassObject and also addObject method 
    // Eventhoug I mocked it seems to me that as otherClassObject is being created here locally 
    // I am unable to mock it.
    ReponseObject reponseObject = otherClassObject.addObject(dtoObject);

    // do some other stuff using the reponseObject
  }
}
public class TestClassToBeTested {
@Tested private ClassToBeTested classBeingTested;
@Injectable SomeOtherClass innerSomeOtherClass;

RequestObject myRequestObject = new RequestObject();
myRequestObject.setSomevalue1("1");
myRequestObject.setSomevalue2("2");

ResponseObject myMockResponseObject = new ResponseObject();
myMockResponseObject.setResultCode(SUCCESS);

@Test
public void shouldTestSomething() {
    new NonStrictExpectations(){{
        // Here I am returning the mocked response object.
        SomeOtherClass.addObject((SomeOtherClass)any);
        result =myMockResponseObject;
    }};   

    classBeingTested.myMethodToBeTested(); 

    // ... 
 }
}
// This is the class to be tested
public class MyMainClass {

public ResponseObject addItem(ProductList products) {

ResponseObject responseObject = new ResponseObject();

OtherService otherService = new OtherService();

List<Product> productList = new ArrayList<Product>();
productList = products.getProducts();

for (int i = 0; i < productList.size(); i++) {
  Product product = otherService.addProduct(productList.get(i));
  System.out.println("model.Product " + product.getName() + " added 
  successfully");
}

responseObject.setResponseCode("1");
responseObject.setResponseMessage("Success");
return responseObject;
 }
}

// Some other service internally used by MyMainClass
public class OtherService implements IService{
 public Product addProduct(Product product){

  // Some business logic to process the product
  System.out.println("Adding product :"+product.getName());

  return product;
  }
}

// Interface implemented by OtherService
public interface IService {

 Product addProduct(Product product);

}

// Sample ResponseObject class 
public class ResponseObject {

String responseCode;
String responseMessage;

public String getResponseMessage() {
   return responseMessage;
}

public void setResponseMessage(String responseMessage) {
   this.responseMessage = responseMessage;
}

public String getResponseCode() {
  return responseCode;
}

public void setResponseCode(String responseCode) {
  this.responseCode = responseCode;
}
}
public class MyMainClassTest {

@Tested
MyMainClass myMainClass;

@Mocked
IService otherService;

private List<Product> myProducts = new ArrayList<Product>();

@Before
public void init(){

  Product product1 = new Product();
  product1.setName("Test1");
  product1.setPid(1);
  product1.setPrice(100.00);
  myProducts.add(product1);
  Product product2 = new Product();
  product2.setName("Test2");
  product2.setPid(2);
  product2.setPrice(200.00);
  myProducts.add(product2);
}

@Test
public void addItem_Test() throws  Exception{
 myMainClass = new MyMainClass();

 new NonStrictExpectations(){{
  otherService.addProduct((Product)any);
  returns(myProducts.get(0));
 }};

 ProductList productList = new ProductList();
 productList.setProducts(myProducts);
 ResponseObject responseObject = myMainClass.addItem(productList);

 Assert.assertEquals(responseObject.getResponseMessage(),"Success");
}
}
我模拟了SomeOther类及其方法,但运气不好,不确定使用JMockit模拟它的正确方法

SomeOtherClass及其方法addObject

尽管我在测试类中模拟了它,但它在要测试的方法中得到了清除。我发现有人问了类似的问题,但解决方案使用了其他一些单元测试框架Mockito。我正在努力使用JMokcit找到类似的解决方案。有谁能帮我找到解决办法吗

下面是我更新的代码示例

正在测试的类和方法:

// class being used in the class to be tested
public class SomeOtherClass{

public ResponseObject addObject(Request dtoObject){
    /// Some business logic goes here

    return reponseObject;
  }
} 

// Class to be tested
public class ClassToBeTested {

public ClassToBeTested() {}

public void myMethodToBeTested() {
    SomeOtherClass otherClassObject = new SomeOtherClass();

    // Here I want mock the otherClassObject and also addObject method 
    // Eventhoug I mocked it seems to me that as otherClassObject is being created here locally 
    // I am unable to mock it.
    ReponseObject reponseObject = otherClassObject.addObject(dtoObject);

    // do some other stuff using the reponseObject
  }
}
public class TestClassToBeTested {
@Tested private ClassToBeTested classBeingTested;
@Injectable SomeOtherClass innerSomeOtherClass;

RequestObject myRequestObject = new RequestObject();
myRequestObject.setSomevalue1("1");
myRequestObject.setSomevalue2("2");

ResponseObject myMockResponseObject = new ResponseObject();
myMockResponseObject.setResultCode(SUCCESS);

@Test
public void shouldTestSomething() {
    new NonStrictExpectations(){{
        // Here I am returning the mocked response object.
        SomeOtherClass.addObject((SomeOtherClass)any);
        result =myMockResponseObject;
    }};   

    classBeingTested.myMethodToBeTested(); 

    // ... 
 }
}
// This is the class to be tested
public class MyMainClass {

public ResponseObject addItem(ProductList products) {

ResponseObject responseObject = new ResponseObject();

OtherService otherService = new OtherService();

List<Product> productList = new ArrayList<Product>();
productList = products.getProducts();

for (int i = 0; i < productList.size(); i++) {
  Product product = otherService.addProduct(productList.get(i));
  System.out.println("model.Product " + product.getName() + " added 
  successfully");
}

responseObject.setResponseCode("1");
responseObject.setResponseMessage("Success");
return responseObject;
 }
}

// Some other service internally used by MyMainClass
public class OtherService implements IService{
 public Product addProduct(Product product){

  // Some business logic to process the product
  System.out.println("Adding product :"+product.getName());

  return product;
  }
}

// Interface implemented by OtherService
public interface IService {

 Product addProduct(Product product);

}

// Sample ResponseObject class 
public class ResponseObject {

String responseCode;
String responseMessage;

public String getResponseMessage() {
   return responseMessage;
}

public void setResponseMessage(String responseMessage) {
   this.responseMessage = responseMessage;
}

public String getResponseCode() {
  return responseCode;
}

public void setResponseCode(String responseCode) {
  this.responseCode = responseCode;
}
}
public class MyMainClassTest {

@Tested
MyMainClass myMainClass;

@Mocked
IService otherService;

private List<Product> myProducts = new ArrayList<Product>();

@Before
public void init(){

  Product product1 = new Product();
  product1.setName("Test1");
  product1.setPid(1);
  product1.setPrice(100.00);
  myProducts.add(product1);
  Product product2 = new Product();
  product2.setName("Test2");
  product2.setPid(2);
  product2.setPrice(200.00);
  myProducts.add(product2);
}

@Test
public void addItem_Test() throws  Exception{
 myMainClass = new MyMainClass();

 new NonStrictExpectations(){{
  otherService.addProduct((Product)any);
  returns(myProducts.get(0));
 }};

 ProductList productList = new ProductList();
 productList.setProducts(myProducts);
 ResponseObject responseObject = myMainClass.addItem(productList);

 Assert.assertEquals(responseObject.getResponseMessage(),"Success");
}
}
//这是要测试的类
公共类MyMainClass{
公共响应对象附加项(产品列表产品){
ResponseObject ResponseObject=新的ResponseObject();
OtherService OtherService=新的OtherService();
List productList=new ArrayList();
productList=products.getProducts();
对于(int i=0;i
测试类:

// class being used in the class to be tested
public class SomeOtherClass{

public ResponseObject addObject(Request dtoObject){
    /// Some business logic goes here

    return reponseObject;
  }
} 

// Class to be tested
public class ClassToBeTested {

public ClassToBeTested() {}

public void myMethodToBeTested() {
    SomeOtherClass otherClassObject = new SomeOtherClass();

    // Here I want mock the otherClassObject and also addObject method 
    // Eventhoug I mocked it seems to me that as otherClassObject is being created here locally 
    // I am unable to mock it.
    ReponseObject reponseObject = otherClassObject.addObject(dtoObject);

    // do some other stuff using the reponseObject
  }
}
public class TestClassToBeTested {
@Tested private ClassToBeTested classBeingTested;
@Injectable SomeOtherClass innerSomeOtherClass;

RequestObject myRequestObject = new RequestObject();
myRequestObject.setSomevalue1("1");
myRequestObject.setSomevalue2("2");

ResponseObject myMockResponseObject = new ResponseObject();
myMockResponseObject.setResultCode(SUCCESS);

@Test
public void shouldTestSomething() {
    new NonStrictExpectations(){{
        // Here I am returning the mocked response object.
        SomeOtherClass.addObject((SomeOtherClass)any);
        result =myMockResponseObject;
    }};   

    classBeingTested.myMethodToBeTested(); 

    // ... 
 }
}
// This is the class to be tested
public class MyMainClass {

public ResponseObject addItem(ProductList products) {

ResponseObject responseObject = new ResponseObject();

OtherService otherService = new OtherService();

List<Product> productList = new ArrayList<Product>();
productList = products.getProducts();

for (int i = 0; i < productList.size(); i++) {
  Product product = otherService.addProduct(productList.get(i));
  System.out.println("model.Product " + product.getName() + " added 
  successfully");
}

responseObject.setResponseCode("1");
responseObject.setResponseMessage("Success");
return responseObject;
 }
}

// Some other service internally used by MyMainClass
public class OtherService implements IService{
 public Product addProduct(Product product){

  // Some business logic to process the product
  System.out.println("Adding product :"+product.getName());

  return product;
  }
}

// Interface implemented by OtherService
public interface IService {

 Product addProduct(Product product);

}

// Sample ResponseObject class 
public class ResponseObject {

String responseCode;
String responseMessage;

public String getResponseMessage() {
   return responseMessage;
}

public void setResponseMessage(String responseMessage) {
   this.responseMessage = responseMessage;
}

public String getResponseCode() {
  return responseCode;
}

public void setResponseCode(String responseCode) {
  this.responseCode = responseCode;
}
}
public class MyMainClassTest {

@Tested
MyMainClass myMainClass;

@Mocked
IService otherService;

private List<Product> myProducts = new ArrayList<Product>();

@Before
public void init(){

  Product product1 = new Product();
  product1.setName("Test1");
  product1.setPid(1);
  product1.setPrice(100.00);
  myProducts.add(product1);
  Product product2 = new Product();
  product2.setName("Test2");
  product2.setPid(2);
  product2.setPrice(200.00);
  myProducts.add(product2);
}

@Test
public void addItem_Test() throws  Exception{
 myMainClass = new MyMainClass();

 new NonStrictExpectations(){{
  otherService.addProduct((Product)any);
  returns(myProducts.get(0));
 }};

 ProductList productList = new ProductList();
 productList.setProducts(myProducts);
 ResponseObject responseObject = myMainClass.addItem(productList);

 Assert.assertEquals(responseObject.getResponseMessage(),"Success");
}
}
公共类MyMainClassTest{
@测试
MyMainClass MyMainClass;
@嘲弄
iSeries服务;
private List myProducts=new ArrayList();
@以前
公共void init(){
product1=新产品();
product1.setName(“Test1”);
产品1.设定PID(1);
产品1.设定价格(100.00);
myProducts.add(product1);
product2=新产品();
product2.setName(“Test2”);
产品2.设定PID(2);
产品2.设定价格(200.00);
myProducts.add(product2);
}
@试验
public void addItem_Test()引发异常{
myMainClass=新的myMainClass();
新的非严格测量(){{
其他服务。添加产品((产品)任何);
返回(myProducts.get(0));
}};
ProductList ProductList=新产品列表();
productList.setProducts(myProducts);
ResponseObject ResponseObject=myMainClass.addItem(产品列表);
Assert.assertEquals(responseObject.getResponseMessage(),“Success”);
}
}
在尝试和分析问题后,我发现了问题所在。我将在答案部分更新解决方案,以便对其他人也有帮助


谢谢。

您只需使用
@Mocked
即可。查看JMockit或API文档,有很多示例。

再次尝试并调试后,我发现了问题所在。我做错的是模仿接口(iSeries),因此它不起作用。当我将其更改为模拟实现的类(OtherService)时,它工作正常

所以在测试课上我换了

@Mocked IService otherService;

在这次改变之后,我的问题得到了解决


谢谢

不要在
mymethodtobetest()
内部创建
SomeOtherClass
,而是在上面的级别创建它,并作为参数
mymethodtobetest(otherClassObject)
发送。在这种情况下,您可以在测试中模拟它。@BorLaze谢谢您的回答。但是如果不改变要测试的类来模拟其他类,就没有其他方法了,就像使用JMockit中建议的解决方案一样?我试图为您的代码编写测试,但这是不可能的,因为它充满了错误。。。(不编译,调用不同的方法,显然应该是同一个方法,等等)如果你能清理它,那会有帮助。@Rogério为这段代码感到抱歉。我已经用正确的工作样本代码更新了我的问题。谢谢回复。事实上,我也试过“嘲弄”,但还是不起作用。一旦我输入myMethodToBeTested方法,模拟对象就没有效果,并且在该方法中创建的对象将覆盖模拟对象。但正如BorLaze所建议的,当我将otherClassObject作为参数传递给MyMethodToBetest时,它就工作了。你是对的@Mocked实际上工作了,但在我的例子中,我模拟了服务接口(iSeries),因此它不工作。因此,我应该模拟实现的类,而不是模拟接口。在模拟实现的类OtherService之后。谢谢我会相应地更新。