Bagaimana cara menguji ClassLoader kustom?

8

Untuk beberapa alasan, saya perlu anak-anak ClassLoader. Seperti ClassLoaderitu tidak ada di JDK, jadi saya menulisnya. Karena ini adalah komponen utama dari use case saya, saya ingin ini diuji berat. Untuk memastikan itu tidak berubah tanpa merusak perilaku, saya ingin menjadi sangat teliti dan menguji semua yang dapat diuji secara otomatis.

Jadi bagaimana saya bisa mengujinya? Bagaimana saya harus melakukan tes unit dasar saya? Saya agak bingung harus mulai dari mana (terutama karena setidaknya ada satu superpanggilan dalam setiap metode) dan saya sedang mencari beberapa panduan untuk memulai.

Ide utama saya adalah sebagai berikut. Apakah ada yang salah dengan itu?

/src/main/resources/parent.jar
                    child.jar

File parent.jarberisi kelas com.example.Exampleyang merupakan dasar Supplierpengembalian "parent". File child.jarberisi kelas com.example.Exampleyang merupakan dasar Supplierpengembalian "child".

Saya akan membuat standar URLClassLoaderuntuk parent.jar, dan saya akan menggunakan kebiasaan saya ClassLoaderuntuk memuat child.jar. Maka saya akan memuat kelas com.example.Exampledan memeriksa bahwa itu benar-benar kembali "child"bukan "parent".

Kasus uji yang lebih kompleks dipikirkan, tetapi saya hanya perlu konfirmasi untuk memulai: apakah ini cukup untuk tes dasar? Apakah ini benar-benar yang harus saya uji dalam unit test saya? Jika tidak, apa itu?


Saya cukup yakin kode ini tidak diperlukan untuk ini, tetapi jika Anda penasaran atau apa pun, ini dia.

import java.io.*;
import java.net.*;
import java.util.*;

class ChildFirstClassLoader extends URLClassLoader {

  ChildFirstClassLoader(ClassLoader parent) {
    super(new URL[0], parent);
  }

  @Override
  // Make this method available in this package.
  protected void addURL(URL url) {
    super.addURL(url);
  }

  @Override
  protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
      Class<?> c = findLoadedClass(name);
      if (c == null) {
        try {
          c = findClass(name);
        } catch (ClassNotFoundException ignore) {
          c = super.loadClass(name, resolve);
        }
      }
      if (resolve) {
        resolveClass(c);
      }
      return c;
    }
  }

  @Override
  public URL getResource(String name) {
    URL url = findResource(name);
    if (url == null) {
      url = super.getResource(name);
    }
    return url;
  }

  @Override
  public Enumeration<URL> getResources(String name) throws IOException {
    List<URL> urls = new ArrayList<>();
    urls.addAll(Collections.list(findResources(name)));
    urls.addAll(Collections.list(super.getResources(name)));
    return Collections.enumeration(urls);
  }
}
Olivier Grégoire
sumber
1
Ya, Anda punya ide yang tepat. Anda perlu memvalidasi bahwa (1) untuk setiap kelas bernama "X" Anda menyelesaikan X oleh classloader yang tepat, dan (2) bahwa classloader akan mendelegasikan setiap permintaan yang tidak dapat dipenuhi.
kdgregory
(dan pertanyaan ini mungkin lebih cocok untuk SO daripada PSE)
kdgregory
1
Pada SO, saya khawatir pertanyaan ini akan ditutup sebagai topik karena meminta pendapat tentang pengujian yang tepat.
Olivier Grégoire
Ya, sedih karena kami terkadang dibuat takut untuk mengirim pertanyaan.
Djangofan

Jawaban:

2

Jadi bagaimana saya bisa mengujinya? Bagaimana saya harus melakukan tes unit dasar saya? Saya agak bingung harus mulai dari mana (terutama karena setidaknya ada satu panggilan super di setiap metode) dan saya sedang mencari beberapa panduan untuk memulai.

Memang saya tidak tahu banyak tentang ClassLoaders atau Java dalam hal ini, tapi saya akan mengalami kesulitan unit menguji ini. Salah satu alasannya adalah, seperti yang Anda nyatakan, kelas Anda mewarisi dari URLClassLoader. Bahkan jika kita bisa mengejek superclass entah bagaimana, saya tidak akan memiliki banyak kepercayaan pada tes memverifikasi bahwa implementasi saya melakukan apa yang seharusnya dilakukan.

Jadi untuk apa nilainya, saya akan bersandar pada penulisan tes yang lebih terintegrasi di sini: Mungkin memiliki beberapa folder "fixture" yang berisi contoh-contoh seperti yang Anda sajikan:

  • Perlengkapan
    • CanSuccessfullyLoad
      • parent.jar
      • child.jar
    • ThrowsAnErrorOnLoad
      • justparent.jar

Itu akan menghasilkan saya menulis tes untuk masing-masing kasus dan "menggunakan" kelas orang tua / anak dengan cara yang sangat sederhana hanya untuk memverifikasi itu dimuat atau gagal dimuat seperti yang saya harapkan.

pengguna1777136
sumber