Как смоделировать локальный объект, создаваемый в тестируемом методе с использованием JMockit - PullRequest
1 голос
/ 31 мая 2019

Я не могу смоделировать экземпляр класса, который создается внутри метода, который я пытаюсь проверить.Ниже приведен пример, иллюстрирующий проблему.

Класс и метод тестирования:

// 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(); 

    // ... 
 }
}

Я издевался над SomeOtherClass и его методом, но не повезло, не уверен, как правильно его смоделировать с помощью JMockit.

SomeOtherClass и его метод addObject

Хотя я и издевался над ним в классе Test, но он очищается в тестируемом методе.Я нашел похожий вопрос, задаваемый ЗДЕСЬ , но в решении используется какая-то другая платформа модульного тестирования Mockito.Я изо всех сил пытаюсь найти подобное решение, используя JMokcit.Может ли кто-нибудь помочь мне найти решение для этого?

Ниже приведен мой обновленный пример кода

Класс и метод, который тестируется:

// 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");
}
}

После попытки и анализа проблемы я нашел, что пошло не так.Я обновлю решение в разделе ответов, чтобы оно было полезно и другим.

Спасибо.

Ответы [ 2 ]

1 голос
/ 01 июня 2019

Вы просто используете @Mocked для этого. Посмотрите учебник по JMockit или документацию по API, есть множество примеров.

0 голосов
/ 05 июня 2019

После повторной попытки отладки я обнаружил, что это не так.Что я делал не так, так это издевался над интерфейсом (IService) и, следовательно, он не работал.Когда я изменил его, чтобы смоделировать реализованный класс (OtherService), он работал правильно.

Таким образом, в классе Test я заменил

@Mocked IService otherService;

на

@Mocked OtherService otherService;

После этого изменения моя проблема была решена.

Спасибо

...