Reputation: 3556
How to make this test pass without using the Subject class or .NET events?
[TestClass]
public class ObservableTests
{
private readonly Subject<Unit> _subject = new Subject<Unit>();
[TestMethod]
public void ObservesMethodCall()
{
var eventCount = 0;
IObservable<Unit> observable = _subject.AsObservable();
observable.Subscribe(u => eventCount++);
Assert.AreEqual(0, eventCount);
Foo();
Assert.AreEqual(1, eventCount);
}
private void Foo()
{
_subject.OnNext(Unit.Default);
}
}
I want to avoid using subjects as they are not recommended. I don't want to use .NET events as RxNet supersedes them.
Related questions:
Firing an event every time a new method is called
It assumes we cannot modify the method being called.
How to create Observable that emits every time a member variable is updated (onCompleted never called)
Uses subjects.
Is there a way to create an observable sequence triggered by method calls without using Subject?
States Subjects are the way to go. However, I still want to learn how to do it without Subjects.
IObserver and IObservable in C# for Observer vs Delegates, Events
Shows how to solve the problem by implementing custom IObservable
Upvotes: 5
Views: 2472
Reputation: 14350
In short, you want to procedurally trigger an observable, but without using subjects or events. You could use a custom delegate (@Enigmativity's answer), and you could also custom implement IObservable (basically re-inventing Subjects).
I'm going to contest the premise though: Use a subject. They aren't always recommended, but they suit your contrived problem as presented.
The bigger question you should be asking though is why you want to procedurally trigger an observable: The whole point of System.Reactive is that you can just worry about one side of a message: Either the receiver (observable) or sender (observer). You're trying to do both, which is what a Subject is. The problem with Subjects isn't some sort of implementation detail, or dogma (Subjects bad, Observables good), it's that the goal is to just focus on receiving messages, not sending and receiving.
Upvotes: 3
Reputation: 117064
This might be a bit like splitting hairs, but this works without the need of a subject:
[TestClass]
public class ObservaleTests
{
private Action _action = null;
[TestMethod]
public void ObservesMethodCall()
{
var eventCount = 0;
IObservable<Unit> observable =
Observable.FromEvent(a => _action += a, a => _action -= a);
observable.Subscribe(u => eventCount++);
Assert.AreEqual(0, eventCount);
Foo();
Assert.AreEqual(1, eventCount);
}
private void Foo()
{
_action();
}
}
Upvotes: 3