デコシノニッキ

ホロレンジャーの戦いの記録

UnityUWPでもZenject x Moqが使いたかった

久しく書いていなかったのでメモ書きがてら。
最近お仕事で,最近はやりのDIコンテナツールであるZenjectを使い始めたのですが,非常に使ってて楽しい。

(資料とても学びがあります) connpass.com

本来であれば,疎結合とはなんたるかから理解すべきだったのですが,まあ結果的に疎結合について学ぶきっかけになったなと。

というのは置いておいて,最近テストを書くようになりました(パチパチ
そうなるとテスト用にモックなんかを作ったりするわけです。Zenjectでは"Moq"というライブラリを使っており,PackageにZipで同梱されています。

ここでいきなり本題にいくのですが,

AutoMockingがUWPでビルドできません(またおまえか)

となると心を無にして,

#if !UNITY_UWP
//††† 封印 †††
#endif

なんて書くわけですが,影響範囲もわからず,そんなハートフルな手作業はやりたくないです。

ヒントになったのはここ,さすがテラシュールブログ。
tsubakit1.hateblo.jp

攻略法はEditor配下をAssemblyDefinitionで切り捨てます。

そもそもPlayModeTest,UWPでビルドできないしな!ははは!


AutoMockingの構成は,Zenject/OptionalExtras/AutoMocking/Editor/Moq-Net46/plugins のような構成になっています。

Editor配下のMoq-Net46などがある階層にCreateからAssemblyDefinitionを作成します。

設定はこんな感じで。
f:id:haikage1755:20180911013957p:plain:w350
これでEditor配下はEditorのみでしかインポートされなくなります。

また,呼ぶ方もAssemblyDefinitionが必要です。
テスト用のディレクトリにAssemblyDefinitionを作成し,参照を解決してやります。

f:id:haikage1755:20180911014249p:plain:w350

ここまでお膳立てして漸くMoqが使えるようになります。はい。

using System.Collections;
using Moq;
using UnityEngine;
using UnityEngine.TestTools;

public interface IFoo {
    string SaySomething();
}

public class Bar : IInitializable {
    private IFoo foo;

    public Bar(IFoo foo) {
        this.foo = foo; 
    }

    public void Initialize() {
        Debug.Log(foo.SaySomething());
    }
}

public class UntitledIntegrationTest : ZenjectIntegrationTestFixture
{
    [UnityTest]
    public IEnumerator RunTest1()
    {
        //MockをつくってBindできる!
        var mock = new Mock<IFoo>();
        mock.Setup(x => x.SaySomething()).Returns("Completely Understantood.");

        PreInstall();
        Container.BindInstance(mock.Object).AsSingle();
        Container.BindInterfacesAndSelfTo<Bar>().AsSingle();
        PostInstall();
        yield break;
    }
}

上はPlayModeテストの話ですが,EditorテストであればEditor配下に普通にテスト作ればAssemblyDefinitionなしに参照できます。

[デコシノニッキ]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」