Skip to content

Commit 0cf8f10

Browse files
Functional RunIn Mock and Time Travel functionality (#299)
* Added State() Functionality to RxAppMock * Added Mock for RunIn Co-authored-by: Eugene Niemand <[email protected]>
1 parent 74a2ab1 commit 0cf8f10

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

src/Fakes/NetDaemon.Fakes/NetDaemon.Fakes.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<ProjectReference Include="..\..\Daemon\NetDaemon.Daemon\NetDaemon.Daemon.csproj" />
2929
</ItemGroup>
3030
<ItemGroup>
31+
<PackageReference Include="Microsoft.Reactive.Testing" Version="5.0.0" />
3132
<PackageReference Include="Moq" Version="4.16.0" />
3233
<PackageReference Include="xunit" Version="2.4.1" />
3334
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

src/Fakes/NetDaemon.Fakes/RxAppMock.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Linq;
99
using System.Reactive.Linq;
10+
using Microsoft.Reactive.Testing;
1011

1112
namespace NetDaemon.Daemon.Fakes
1213
{
@@ -27,10 +28,15 @@ public class RxAppMock : Mock<INetDaemonRxApp>
2728
public ObservableBase<(EntityState Old, EntityState New)> StateChangesObservable { get; }
2829

2930
/// <summary>
30-
/// Observalbe fake events
31+
/// Observable fake events
3132
/// </summary>
3233
public ObservableBase<RxEvent> EventChangesObservable { get; }
3334

35+
/// <summary>
36+
/// This is a Scheduler to support time travel for Observable Timer and Interval
37+
/// </summary>
38+
public TestScheduler TestScheduler { get; } = new();
39+
3440
/// <summary>
3541
/// Default constructor
3642
/// </summary>
@@ -76,6 +82,13 @@ public RxAppMock()
7682
m.Setup(e => e.TurnOff(It.IsAny<object?>())).Throws(new NotImplementedException());
7783
return m.Object;
7884
});
85+
86+
Setup(s => s.RunIn(It.IsAny<TimeSpan>(), It.IsAny<Action>()))
87+
.Callback<TimeSpan, Action>((span, action) =>
88+
{
89+
Observable.Timer(span, TestScheduler)
90+
.Subscribe(_ => action());
91+
});
7992
}
8093

8194
private void UpdateMockState(string[] entityIds, string newState, object? attributes)

tests/NetDaemon.Daemon.Tests/FakesTests/FakeMockableApp.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public void Initialize()
7676
if (_app.State("sensor.some_other_entity")?.State == "on")
7777
_app.Entity("light.state_light").TurnOn();
7878
});
79+
80+
_app.RunIn(TimeSpan.FromMilliseconds(100), () => _app.Entity("binary_sensor.fake_run_in_happened").TurnOn());
7981
}
8082

8183
}

tests/NetDaemon.Daemon.Tests/FakesTests/RxMockTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ public void TestFakeMockableBinarySensorAppEntitiesFalse()
128128
VerifyEntityTurnOn("light.kitchen", times: Times.Never());
129129
}
130130

131+
[Fact]
132+
public void TestFakeRunIn()
133+
{
134+
// ARRANGE
135+
FakeMockableAppImplementation app = new(Object);
136+
app.Initialize();
137+
138+
// ACT
139+
TestScheduler.AdvanceBy(TimeSpan.FromMilliseconds(100).Ticks);
140+
141+
// ASSERT
142+
VerifyEntityTurnOn("binary_sensor.fake_run_in_happened", times: Times.Once());
143+
}
144+
131145
[Fact]
132146
public void TestFakeEventTurnsOnLight()
133147
{

0 commit comments

Comments
 (0)