Pertanyaan Mencemooh konstruktor dengan parameter


Saya memiliki kelas seperti di bawah ini:

public class A {
    public A(String test) {
        bla bla bla
    }

    public String check() {
        bla bla bla
    }
}

Logika dalam konstruktor A(String test) dan check() adalah hal-hal yang saya coba tirukan. Saya ingin panggilan seperti: new A($$$any string$$$).check() mengembalikan string dummy "test".

Saya mencoba:

 A a = mock(A.class); 
 when(a.check()).thenReturn("test");

 String test = a.check(); // to this point, everything works. test shows as "tests"

 whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk);
 // also tried:
 //whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk);

 new A("random string").check();  // this doesn't work

Tapi sepertinya tidak berhasil. new A($$$any string$$$).check() masih melalui logika konstruktor bukannya mengambil objek yang diejek A.


61
2017-11-13 16:17


asal


Jawaban:


Kode yang Anda poskan berfungsi untuk saya dengan versi terbaru Mockito dan Powermockito. Mungkin Anda belum menyiapkan A? Coba ini:

A.java

public class A {
     private final String test;

    public A(String test) {
        this.test = test;
    }

    public String check() {
        return "checked " + this.test;
    }
}

MockA.java

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class MockA {
    @Test
    public void test_not_mocked() throws Throwable {
        assertThat(new A("random string").check(), equalTo("checked random string"));
    }
    @Test
    public void test_mocked() throws Throwable {
         A a = mock(A.class); 
         when(a.check()).thenReturn("test");
         PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a);
         assertThat(new A("random string").check(), equalTo("test"));
    }
}

Kedua tes harus lulus dengan mockito 1.9.0, powermockito 1.4.12 dan junit 4.8.2


63
2017-11-13 17:32



Sepengetahuan saya, Anda tidak bisa mengejek konstruktor dengan mockito, hanya metode. Tetapi menurut wiki di halaman kode Google Mockito ada cara untuk mengejek perilaku konstruktor dengan membuat metode di kelas Anda yang mengembalikan contoh baru dari kelas itu. maka Anda bisa mencemooh metode itu. Di bawah ini adalah sebuah kutipan langsung dari wiki Mockito:

Pola 1 - menggunakan metode satu baris untuk pembuatan objek

Untuk menggunakan pola 1 (menguji kelas yang disebut MyClass), Anda akan mengganti panggilan seperti

   Foo foo = new Foo( a, b, c );

dengan

   Foo foo = makeFoo( a, b, c );

dan menulis metode satu baris

   Foo makeFoo( A a, B b, C c ) { 
        return new Foo( a, b, c );
   }

Sangat penting bahwa Anda tidak menyertakan logika apa pun dalam metode ini; hanya satu baris yang menciptakan   obyek. Alasannya adalah bahwa metode itu sendiri tidak akan pernah ada   menjadi unit diuji.

Ketika Anda datang untuk menguji kelas, objek yang akan Anda uji   sebenarnya menjadi mata-mata Mockito, dengan metode ini ditimpa, untuk mengembalikan a   mengejek. Apa yang Anda uji karena itu bukan kelas itu sendiri, tetapi a   versi yang sangat sedikit dimodifikasi.

Kelas tes Anda mungkin berisi anggota suka

  @Mock private Foo mockFoo;
  private MyClass toTest = spy(new MyClass());

Terakhir, di dalam metode pengujian Anda Anda mencemooh panggilan untuk   makeFoo dengan garis seperti

  doReturn( mockFoo )
      .when( toTest )
      .makeFoo( any( A.class ), any( B.class ), any( C.class ));

Anda dapat menggunakan matchers yang lebih spesifik daripada () jika Anda mau   periksa argumen yang dilewatkan ke konstruktor.

Jika Anda hanya ingin mengembalikan objek yang diejek kelas Anda, saya pikir ini akan bekerja untuk Anda. Dalam hal apa pun Anda dapat membaca lebih lanjut tentang pembuatan objek tiruan di sini:

http://code.google.com/p/mockito/wiki/MockingObjectCreation


36
2017-11-13 17:12



Tanpa Menggunakan Powermock .... Lihat contoh di bawah ini berdasarkan jawaban Ben Glasser karena saya butuh waktu untuk mengetahuinya .. berharap dapat menghemat waktu ...

Kelas Asli:

public class AClazz {

    public void updateObject(CClazz cClazzObj) {
        log.debug("Bundler set.");
        cClazzObj.setBundler(new BClazz(cClazzObj, 10));
    } 
}

Kelas yang dimodifikasi:

@Slf4j
public class AClazz {

    public void updateObject(CClazz cClazzObj) {
        log.debug("Bundler set.");
        cClazzObj.setBundler(getBObject(cClazzObj, 10));
    }

    protected BClazz getBObject(CClazz cClazzObj, int i) {
        return new BClazz(cClazzObj, 10);
    }
 }

Kelas Tes 

public class AClazzTest {

    @InjectMocks
    @Spy
    private AClazz aClazzObj;

    @Mock
    private CClazz cClazzObj;

    @Mock
    private BClazz bClassObj;

    @Before
    public void setUp() throws Exception {
        Mockito.doReturn(bClassObj)
               .when(aClazzObj)
               .getBObject(Mockito.eq(cClazzObj), Mockito.anyInt());
    }

    @Test
    public void testConfigStrategy() {
        aClazzObj.updateObject(cClazzObj);

        Mockito.verify(cClazzObj, Mockito.times(1)).setBundler(bClassObj);
    }
}

10
2017-12-14 11:06



Mockito memiliki keterbatasan untuk menguji metode final, statis, dan pribadi.

dengan pustaka pengujian jMockit, Anda dapat melakukan beberapa hal dengan sangat mudah dan lurus ke depan seperti di bawah ini:

Konstruktor tiruan dari kelas java.io.File:

new MockUp<File>(){
    @Mock
    public void $init(String pathname){
        System.out.println(pathname);
        // or do whatever you want
    }
};
  • nama konstruktor publik harus diganti dengan $ init
  • argumen dan pengecualian yang dilemparkan tetap sama
  • jenis pengembalian harus didefinisikan sebagai batal

Mencemooh metode statis:

  • menghapus statis dari tanda tangan metode mock
  • tanda tangan metode tetap sama jika tidak

1
2018-04-04 20:02