question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using LazyInject in UnitTests

See original GitHub issue

Hi, is it possible to use LazyInject within UnitTests? I tried something like the following and _foo in class Bar (line 13) is always null when executing the UnitTest. I already played around with the order of binding and couldn’t solve this.

Best regards 😃

using System;
using System.Threading.Tasks;
using Zenject;

public class Bar : BarBase, IBar {
    LazyInject<Foo> _foo;

    public Bar(LazyInject<Foo> foo) {
        _foo = foo;
    }

    public async Task<bool> Run() {
        return await _foo.Value.Run();
    }

    public void Register(Action<bool> callback) {
        int a = 5 + 2;
        callback.Invoke(true);
    }
}
public class BarBase {
    public BarBase() { }
}
using System;
using System.Threading.Tasks;

public interface IBar {
    Task<bool> Run();
    void Register(Action<bool> callback);
}
using System.Threading.Tasks;

public class Foo : IFoo {
    public async Task<bool> Run() {
        await Task.Delay(1000);
        return true;
    }
}
using System.Threading.Tasks;

public interface IFoo {
    Task<bool> Run();
}
using Moq;
using NUnit.Framework;
using System;
using Zenject;

[TestFixture]
public class FooBarUnitTest : ZenjectUnitTestFixture {

    [Inject]
    IBar _bar;
    [Inject]
    IFoo _foo;

    [SetUp]
    public void CommonInstall() {

        Container.Bind<IFoo>().To<Foo>().AsSingle();

        Mock<IBar> bar = new Mock<Bar>(_foo).As<IBar>();
        bar.CallBase = true;
        bar.Setup(b => b.Register(It.IsAny<Action<bool>>()))
            .Callback<Action<bool>>(async (action) => {
                action.Invoke(await bar.Object.Run());
            }
        );

        Container.BindInstance(bar.Object).AsSingle();
        Container.Inject(this);
    }

    [Test]
    public void TestInitialValues() {
        bool wasRunning = _bar.Run().GetAwaiter().GetResult();

        Assert.True(wasRunning);
    }
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11

github_iconTop GitHub Comments

1reaction
svermeulencommented, May 6, 2019

I think it has something to do with your async code though, not zenject. Maybe check into what SynchronizationContext you’re using, since that will determine how code is continued after an await

0reactions
FireDragonGameStudiocommented, May 6, 2019

Found the issue! The error is caused by Unitys old NUnit version (https://forum.unity.com/threads/async-await-in-unittests.513857/) The execution of async await in UnitTests is… different.

Thank you for pointing me into the right direction 😃 Correct test looks now like this:

using NUnit.Framework;
using System.Threading.Tasks;
using Zenject;

[TestFixture]
public class FooBarUnitTest : ZenjectUnitTestFixture {

    [Inject]
    IBar _bar;

    [SetUp]
    public void CommonInstall() {
        Container.Bind<Foo>().AsSingle();
        Container.Bind<IBar>().To<Bar>().AsSingle();
        Container.Inject(this);
    }

    [Test]
    public void TestInitialValues() {

        bool wasRunning = false;

        wasRunning = Task.Run(() => _bar.Run()).GetAwaiter().GetResult();

        Assert.True(wasRunning);
    }
}

Best regards 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Should initialisation of class-level variable with by lazy in ...
Is it possible to lazily initialize a property and assert it? ... When a value is declared "by lazy" in Kotlin is that...
Read more >
Lazy Dependency Injection for .NET
Instead, it is suggested to use the LazyProxy library, which allows you to get lazy injection benefits while still getting clean code. This ......
Read more >
Writing Easily Testable Code with Autofac & Lazy Properties
This pattern declares an optional constructor-injected dependency as ... With the optional Lazy dependencies, the unit test looks more like:
Read more >
Unit Test to verify number of times lazy initialization logic is ...
In the above class I'm doing lazy initialization of a data member c. Responsibility of class A is to compute this.c from this.a...
Read more >
Roll your own dependency injection in Swift
To solve for this we convert the injector to a class and make all the properties lazy . This ensures that they are...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found