আমি কীভাবে মকিতো সহ স্প্রিংয়ে একটি স্বায়ত্তশাসিত @ ভালু ক্ষেত্রটিকে উপহাস করব?


123

আমি স্প্রিংয়ের ৩.১.৪ ব্যবহার করছি। নিখরচায় এবং মকিতো ১.৯.৫। আমার স্প্রিং ক্লাসে আছে:

@Value("#{myProps['default.url']}")
private String defaultUrl;

@Value("#{myProps['default.password']}")
private String defaultrPassword;

// ...

আমার JUnit পরীক্ষা থেকে, যা আমি বর্তমানে এটির মতো সেট আপ করেছি:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-context.xml" })
public class MyTest 
{ 

আমি আমার "ডিফল্ট ইউআরএল" ক্ষেত্রের জন্য একটি মান উপহাস করতে চাই। মনে রাখবেন যে আমি অন্যান্য ক্ষেত্রগুলির জন্য মানগুলি উপহাস করতে চাই না - আমি সেগুলি কেবল তাদের হিসাবে রাখতে চাই, কেবলমাত্র "ডিফল্টইউআরএল" ক্ষেত্র। আরও মনে রাখবেন যে setDefaultUrlআমার ক্লাসে আমার স্পষ্ট "সেটার" পদ্ধতি নেই (উদাঃ ) এবং আমি পরীক্ষার উদ্দেশ্যে কেবল কোনও তৈরি করতে চাই না।

এটি দেওয়া, আমি কীভাবে সেই এক ক্ষেত্রের জন্য একটি মানকে উপহাস করতে পারি?

উত্তর:


144

ReflectionTestUtils.setFieldআপনার কোডটিতে যে কোনও পরিবর্তন আনতে আপনি বসন্তের যাদু ব্যবহার করতে পারেন ।

পরীক্ষা করে দেখুন এই এমনকি আরও তথ্যের জন্য টিউটোরিয়াল, যেহেতু পদ্ধতি ব্যবহার করা খুবই সহজ, যদিও আপনি সম্ভবত এটি প্রয়োজন হবে না

হালনাগাদ

স্প্রিং ৪.২.আরসি 1 চালু হওয়ার পরে ক্লাসের কোনও উদাহরণ সরবরাহ না করেই এখন একটি স্ট্যাটিক ফিল্ড সেট করা সম্ভব। দেখুন এই নথিপত্রের অংশ এবং এই কমিট।


12
কেবল লিঙ্কটি মারা যাওয়ার ক্ষেত্রে: পরীক্ষার সময় ReflectionTestUtils.setField(bean, "fieldName", "value");আপনার beanপদ্ধতিটি আহ্বানের আগে ব্যবহার করুন ।
মিশা স্টোকমাল

2
বৈশিষ্ট্যগুলি ফাইল থেকে পুনরুদ্ধার করা বৈশিষ্ট্যগুলি উপহাস করার জন্য ভাল সমাধান।
অ্যান্টনি সম্পাথ কুমার রেড্ডি

@ মাইশাস্টোকল, ফাইলটি প্রাইভেট জাভা.এল.আং.ইলিজালস্টেট স্টেক্স এক্সেক্সশন: পদ্ধতি অ্যাক্সেস করতে পারছে না: শ্রেণি org.springframework.util.ReflectionUtils com.kaleidofin.app.service.impl.CVLKraprovider ক্লাসের কোনও সদস্য অ্যাক্সেস করতে পারে না org.springframework.util.RiflectionUtils.handleReflectionException (প্রতিবিম্ব Utils.java split12) এ org.springframework.util.ReflectionUtils.setField (প্রতিচ্ছবি Utils.java:655)
আখিল সুরপুরাম

112

আমি কীভাবে @ ভ্যালু ক্ষেত্রটিকে উপহাস করতে পারি তা ভুলে যাওয়ায় এখন এই তৃতীয় বারের মতো নিজেকে এই এসও পোস্টে গুগল করেছিলাম। যদিও গৃহীত উত্তরটি সঠিক, আমার "সেটফিল্ড" কলটি ডান পেতে সর্বদা আমার কিছুটা সময় প্রয়োজন, তাই কমপক্ষে নিজের জন্য আমি এখানে একটি উদাহরণ স্নিপেট পেস্ট করব:

উত্পাদন শ্রেণি:

@Value("#{myProps[‘some.default.url']}")
private String defaultUrl;

পরীক্ষার শ্রেণি:

import org.springframework.test.util.ReflectionTestUtils;

ReflectionTestUtils.setField(instanceUnderTest, "defaultUrl", "http://foo");
// Note: Don't use MyClassUnderTest.class, use the instance you are testing itself
// Note: Don't use the referenced string "#{myProps[‘some.default.url']}", 
//       but simply the FIELDs name ("defaultUrl")

32

আপনি নিজের পরীক্ষার শ্রেণিতে আপনার সম্পত্তি কনফিগারেশনকেও উপহাস করতে পারেন

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-context.xml" })
public class MyTest 
{ 
   @Configuration
   public static class MockConfig{
       @Bean
       public Properties myProps(){
             Properties properties = new Properties();
             properties.setProperty("default.url", "myUrl");
             properties.setProperty("property.value2", "value2");
             return properties;
        }
   }
   @Value("#{myProps['default.url']}")
   private String defaultUrl;

   @Test
   public void testValue(){
       Assert.assertEquals("myUrl", defaultUrl);
   }
}

25

আমি একটি সম্পর্কিত সমাধান প্রস্তাব করতে চাই, যা ক্লাসটি @Valueব্যবহারের পরিবর্তে নির্ধারিত ক্ষেত্রগুলিকে নির্ধারকের কাছে পরামিতি হিসাবে অ্যানোটেশনযুক্ত ক্ষেত্রগুলি পাস করতে হয় ReflectionTestUtils

এর পরিবর্তে:

public class Foo {

    @Value("${foo}")
    private String foo;
}

এবং

public class FooTest {

    @InjectMocks
    private Foo foo;

    @Before
    public void setUp() {
        ReflectionTestUtils.setField(Foo.class, "foo", "foo");
    }

    @Test
    public void testFoo() {
        // stuff
    }
}

এটা কর:

public class Foo {

    private String foo;

    public Foo(@Value("${foo}") String foo) {
        this.foo = foo;
    }
}

এবং

public class FooTest {

    private Foo foo;

    @Before
    public void setUp() {
        foo = new Foo("foo");
    }

    @Test
    public void testFoo() {
        // stuff
    }
}

এই পদ্ধতির সুবিধাগুলি: 1) আমরা নির্ভরতা ধারক ছাড়াই ফু ক্লাস ইনস্ট্যান্ট করতে পারি (এটি কেবল একজন নির্মাতা) এবং ২) আমরা আমাদের প্রয়োগের বিশদগুলির সাথে আমাদের পরীক্ষাটি সংযুক্ত করছি না (প্রতিফলনটি একটি স্ট্রিং ব্যবহার করে আমাদের ফিল্ডের নামের সাথে সংযুক্ত করে, যা যদি আমরা ক্ষেত্রের নাম পরিবর্তন করি তবে সমস্যার কারণ হতে পারে)।


3
খারাপ দিক: যদি কেউ টীকা দিয়ে ভুল করে, যেমন 'foo' এর পরিবর্তে একটি সম্পত্তি 'বার' ব্যবহার করে, আপনার পরীক্ষাটি এখনও কাজ করবে। আমি এই মামলা আছে।
নিলস এল-হিমেদ

@ নিলসেল-হিমোদ এটি ওপি প্রশ্নের পক্ষে একটি সাধারণ বিষয়, তবে আপনি যে বিষয়টি উত্থাপন করেছেন সেটি বনাম নির্মাণকারীর প্রতিচ্ছবি ব্যবহার করে আরও ভাল বা খারাপ কিছু নয়। এই উত্তরের বিষয়টি হ'ল কনস্ট্রাক্টর ওভার রিফ্লেকশন ইউজ (স্বীকৃত উত্তর) বিবেচনা করা। চিহ্নিত করুন, উত্তরের জন্য ধন্যবাদ, আমি এই ত্বকের স্বাচ্ছন্দ্য এবং পরিচ্ছন্নতার প্রশংসা করি।
মার্কি

22

আপনি এই ম্যাজিক স্প্রিং টেস্ট টীকাটি ব্যবহার করতে পারেন:

@TestPropertySource(properties = { "my.spring.property=20" }) 

দেখুন org.springframework.test.context.TestPropertySource

উদাহরণস্বরূপ, এটি পরীক্ষার শ্রেণি:

@ContextConfiguration(classes = { MyTestClass.Config.class })
@TestPropertySource(properties = { "my.spring.property=20" })
public class MyTestClass {

  public static class Config {
    @Bean
    MyClass getMyClass() {
      return new MyClass ();
    }
  }

  @Resource
  private MyClass myClass ;

  @Test
  public void myTest() {
   ...

এবং এই সম্পত্তি সহ শ্রেণি:

@Component
public class MyClass {

  @Value("${my.spring.property}")
  private int mySpringProperty;
   ...

13

আমি নীচের কোডটি ব্যবহার করেছি এবং এটি আমার পক্ষে কাজ করেছে:

@InjectMocks
private ClassABC classABC;

@Before
public void setUp() {
    ReflectionTestUtils.setField(classABC, "constantFromConfigFile", 3);
}

তথ্যসূত্র: https://www.jeejava.com/mock-an-autowired-value-field-in-spring-with- junit- mockito/


1
এখানে একই ... + 1
সৌম্য

আমি একই কাজ করলাম তবে তা এখনও প্রতিফলিত হচ্ছে না
শুভ্র মুখোপাধ্যায়

1

এছাড়াও নোট করুন যে আমার ক্লাসে আমার স্পষ্ট "সেটার" পদ্ধতি নেই (যেমন setDefaultUrl) এবং আমি কেবল পরীক্ষার উদ্দেশ্যে কোনও তৈরি করতে চাই না।

এটি সমাধানের একটি উপায় হ'ল কনস্ট্রাক্টর ইনজেকশন ব্যবহার করার জন্য আপনার ক্লাস পরিবর্তন করা , এটি টেস্টিং এবং স্প্রিং ইনজেকশনের জন্য ব্যবহৃত হয়। আর প্রতিবিম্ব নেই :)

সুতরাং, আপনি কনস্ট্রাক্টর ব্যবহার করে যে কোনও স্ট্রিং পাস করতে পারবেন:

class MySpringClass {

    private final String defaultUrl;
    private final String defaultrPassword;

    public MySpringClass (
         @Value("#{myProps['default.url']}") String defaultUrl, 
         @Value("#{myProps['default.password']}") String defaultrPassword) {
        this.defaultUrl = defaultUrl;
        this.defaultrPassword= defaultrPassword;
    }

}

এবং আপনার পরীক্ষায়, কেবল এটি ব্যবহার করুন:

MySpringClass MySpringClass  = new MySpringClass("anyUrl", "anyPassword");
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.