Skip to content

A simple library that decomposes targets into primitive data types and asserts them.

License

Notifications You must be signed in to change notification settings

in-async/PrimitiveAssert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

d95149c · Jun 23, 2021

History

50 Commits
Jun 23, 2021
Jun 23, 2021
Feb 16, 2020
Feb 16, 2020
Jun 23, 2021
Feb 16, 2020
Feb 18, 2020
Apr 18, 2020
Jun 23, 2021

Repository files navigation

PrimitiveAssert

Build status NuGet

PrimitiveAssert は対象をプリミティブ データ型に分解してアサートするシンプルなライブラリです。

Target Frameworks

  • .NET Standard 2.0
  • .NET Framework 4.6.1

Description

このライブラリは、任意のデータ型に対して統一された API によって等値アサートを行う事を目的としています。

基本的な使い方は次の通りです:

actual.AssertIs(expected);

PrimitiveAssert.AssertIs() 拡張メソッドは、actual と expected の public かつ instance なデータ メンバーを等値アサート可能な最小単位 "プリミティブ データ" に分解し、比較します。

例えば、下記のようなデータ型 IAccount を返すメソッドをテストする場合:

public interface IAccount {
    int AccountId { get; }
    string Name { get; }
    DateTime CreatedAt { get; }
    IReadOnlyCollection<string> Tags { get; }
}

public class FakeAccountQuery {
    public IAccount Find(int accountId) {
        return new Account {
            AccountId = accountId,
            Name = "John Smith",
            CreatedAt = new DateTime(2020, 3, 9, 8, 15, 0),
            Tags = new []{ "Foo", "Bar" },
        };
    }

    private sealed class Account : IAccount {
        public int AccountId { get; set; }
        public string Name { get; set; }
        public DateTime CreatedAt  { get; set; }
        public IReadOnlyCollection<string> Tags { get; set; }
    }
}

次のように等値アサートが書けます:

var query = new FakeAccountQuery();
var actual = query.Find(123);

actual.AssertIs(new {
    AccountId = 123,
    Name = "John Smith",
    CreatedAt = new DateTime(2020, 3, 9, 8, 15, 0),
    Tags = new []{ "Foo", "Bar" },
});

ここでは expected に匿名型を用いましたが、もちろん IAccount を継承した型を使用する事もできます:

var query = new FakeAccountQuery();
var actual = query.Find(123);

actual.AssertIs(new StubAccount {
    AccountId = 123,
    Name = "John Smith",
    CreatedAt = new DateTime(2020, 3, 9, 8, 15, 0),
    Tags = new[] { "Foo", "Bar" },
});

...

class StubAccount : IAccount {
    public int AccountId { get; set; }
    public string Name { get; set; }
    public DateTime CreatedAt { get; set; }
    public IReadOnlyCollection<string> Tags { get; set; }
}

どのようにアサートが行われているか、その詳細なログが必要な場合は

PrimitiveAssert.ConsoleLogging = true;

とする事で、次のようなログがコンソールに出力されます:

actual: IAccount = {
    AccountId: Int32 = 123    // actual と expected は数値型として等しいです。
    Name: String = "John Smith"    // actual と expected は String 型として等しいです。
    CreatedAt: DateTime = "2020/03/09 8:15:00"    // actual と expected は DateTime 型として等しいです。
    Tags: IReadOnlyCollection<String> = {
        [0]: String = "Foo"    // actual と expected は String 型として等しいです。
        [1]: String = "Bar"    // actual と expected は String 型として等しいです。
    }
}

ターゲット型

比較対象となるデータ メンバーは、public かつ instnace なプロパティ及びフィールドが選ばれますが、時には比較対象から外したいデータ メンバーがあるかも知れません。

interface IFoo {
    string Foo { get; }
}
interface IBar {
    string Bar { get; }
}
class FooBar : IFoo, IBar {
    public string Foo { get; set; }
    public string Bar { get; set; }
}

...

var fooBar = new FooBar {
    Foo = "Foo1",
    Bar = "Bar2",
};

// IFoo として等値アサートしたいが、これだと PrimitiveAssertFailedException がスローされる
fooBar.AssertIs(new {
    Foo = "Foo1",
});

そのような場合はターゲット型を明示する事で対応が可能です:

// IFoo として等値アサートされる。PrimitiveAssertFailedException はスローされない
fooBar.AssertIs<IFoo>(new {
    Foo = "Foo1",
});
// or
fooBar.AssertIs(typeof(IFoo), new {
    Foo = "Foo1",
});

ターゲット型省略時は、actual の変数型がターゲット型となります。従って以下の記述でも IFoo の等値アサートは可能です:

IFoo fooBar = new FooBar {
    Foo = "Foo1",
    Bar = "Bar2",
};

// fooBar.AssertIs<IFoo> と同じ
fooBar.AssertIs(new {
    Foo = "Foo1",
});

また、actual はターゲット型を実装してる必要はなく、ダック タイピング的にデータ メンバーを備えていれば問題ありません。

例えば匿名型を使用して、任意のデータ メンバーのみを等値アサートの対象とする荒業もやろうと思えばできます:

var query = new FakeAccountQuery();
var actual = query.Find(123);

var targetType = new {
    Name = default(string),
}.GetType();

// Name プロパティのみを等値アサートの対象としている
actual.AssertIs(targetType, new {
    Name = "John Smith",
});

About

A simple library that decomposes targets into primitive data types and asserts them.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages