共享篋:目录测试代码解释

篇目

  1. 结构类型StructType自我实现的单元测试代码
  2. 特质TraitCanal实现的单元测试代码
  3. 特质TraitKanal实现的单元测试代码
  4. 所有实现的单元测试代码
  5. 基于模块的单元测试代码
  6. 题外话
  7. 浅说指针类型Box
  8. 参考资料

结构类型StructType自我实现的单元测试代码

  下面单元测试仅仅使用了结构类型StructType的自我实现。四个方法分别测试了:

  • 使用结构类型StructType自我实现的实例化函数new();
  • 使用标准库默认特质Default实现的实例化函数default();
  • 使用结构类型StructType自我实现的方法get_data_for_all();
  • 使用结构类型StructType自我实现的方法set_data_for_all();
use trait_exerci::StructType;

#[test]
fn it_works_with_new() {
    let instance = StructType::new(10);
    assert_eq!(StructType::new(10), instance);
}

#[test]
fn it_works_with_default() {
    let instance :StructType = Default::default();
    assert_eq!(StructType::new(0), instance);
}

#[test]
fn it_works_with_get() {
    let instance = StructType::new(11);
    assert_eq!(11, instance.get_data_for_all());
    assert_eq!(StructType::new(11), instance);
}

#[test]
fn it_works_with_set() {
    let mut instance = StructType::new(0);
    instance.set_data_for_all(&12);
    assert_eq!(StructType::new(12), instance);
}

特质TraitCanal实现的单元测试代码

  下面单元测试使用了结构类型StructType的自我实现和特质TraitCanal实现。特别需要注意的是,从代码表面上看,第二行语句与后面代码没有任何关系。之所以代码里可以使用方法get_data(),就是因为第二行语句的作用。当我们写下第二行语句时,就应该知道接下来我们将要使用什么函数或/和方法。

  方法it_works_with_get()测试了:

  • 使用结构类型StructType自我实现的实例化函数new();
  • 使用特质TraitCanal实现的方法get_data();

  方法it_works_with_default()测试了:

  • 使用标准库默认特质Default实现的实例化函数default();
  • 使用特质TraitCanal实现的方法get_data();
use trait_exerci::StructType;
use trait_exerci::TraitCanal;

#[test]
fn it_works_with_get() {
    let instance = StructType::new(20);
    assert_eq!(20, instance.get_data());
    assert_eq!(StructType::new(20), instance);
}

#[test]
fn it_works_with_default() {
    let instance :StructType = Default::default();
    assert_eq!(0, instance.get_data());
    assert_eq!(StructType::new(0), instance);
}

特质TraitKanal实现的单元测试代码

  下面单元测试使用了结构类型StructType的自我实现和特质TraitKanal实现。所以这里没有使用到特质TraitCanal实现。尽管下面代码没有使用特质TraitCanal实现,但是我们使用了标准库平等比较特质PartialEq,实现了代码测试。

  方法it_works_with_get()测试了:

  • 使用结构类型StructType自我实现的实例化函数new();
  • 使用特质TraitKanal实现的方法get_data();

  方法it_works_with_default()测试了:

  • 使用标准库默认特质Default实现的实例化函数default();
  • 使用特质TraitKanal实现的方法get_data();
use trait_exerci::StructType;
use trait_exerci::TraitKanal;

#[test]
fn it_works_with_set() {
    let mut instance = StructType::new(0);
    instance.set_data(&30);
    assert_eq!(StructType::new(30), instance);
}

#[test]
fn it_works_with_default() {
    let mut instance :StructType = Default::default();
    instance.set_data(&30);
    assert_eq!(StructType::new(30), instance);
}

所有实现的单元测试代码

  下面单元测试程序的所有三个实现。所以最前面三行语句表示使用这三个实现。

use trait_exerci::StructType;
use trait_exerci::TraitCanal;
use trait_exerci::TraitKanal;

#[test]
fn it_works_with_both_traits_and_new() {
    let mut instance = StructType::new(40);
    instance.set_data(&41);
    assert_eq!(41, instance.get_data());
    assert_eq!(StructType::new(41), instance);
}

#[test]
fn it_works_with_both_traits_and_default() {
    let mut instance :StructType = Default::default();
    instance.set_data(&41);
    assert_eq!(41, instance.get_data());
    assert_eq!(StructType::new(41), instance);
}

基于模块的单元测试代码

  下面单元测试主要说明在模块下如何进行单元测试。除了定义模块之外,最重要的是,使用三个实现语句必须在模块内。

#[cfg(test)]
mod tests {
    use trait_exerci::StructType;
    use trait_exerci::TraitCanal;

    #[test]
    fn it_works_with_new() {
        let instance = StructType::new(50);
        assert_eq!(StructType::new(50), instance);
    }

    #[test]
    fn it_works_with_get() {
        let instance = StructType::new(51);
        assert_eq!(51, instance.get_data());
    }

    #[test]
    fn it_works_with_new_and_box() {
        let instance = Box::new(StructType::new(52));
        assert_eq!(Box::new(StructType::new(52)), instance);
    }

    #[test]
    fn it_works_with_get_and_box() {
        let instance = Box::new(StructType::new(53));
        assert_eq!(53, instance.get_data());
    }

    use trait_exerci::TraitKanal;
    #[test]
    fn it_works_with_set() {
        let mut instance = StructType::new(54);
        instance.set_data(&55);
        assert_eq!(StructType::new(55), instance);
    }

    #[test]
    fn it_works_with_set_and_box() {
        let mut instance = Box::new(StructType::new(56));
        instance.set_data(&57);
        assert_eq!(Box::new(StructType::new(57)), instance);
    }
}

题外话

浅说指针类型Box

  Rust标准库提供了类型Box<T>。可以使用该类型Box<T>在堆上分配内容。此类型用于安全地抽象指向堆内存的指针。同时它具有更大的灵活性,允许将实现特质如TraitCanal的任何事物进行Box类型化。

#[derive(Debug, Default)]
pub struct Person {
    name: String,
    age: u32,
}

fn main() {
    let person :Box<Person> = Box::new(Default::default());
    println!("{:?}", person);
}

参考资料